All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/76] target/microblaze improvements
@ 2020-08-28 14:18 Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
                   ` (76 more replies)
  0 siblings, 77 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Thanks for all the testing and review, Edgar.

Changes in v2:
  * Restored opcode_0_illegal handling.
  * Dropped problematic imm/delay slot tb extension.
  * Dropped tcg_gen_lookup_and_goto_ptr for now.
  * Added fix for mb_cpu_transaction_failed.
  * Removed microblaze-decode.h with old decoder.
  * Removed abort_at_next_insn with old decoder.
  * Fixed mbar.
  * Fixed put.


r~


Richard Henderson (76):
  tests/tcg: Add microblaze to arches filter
  tests/tcg: Do not require FE_TOWARDZERO
  tests/tcg: Do not require FE_* exception bits
  target/microblaze: Tidy gdbstub
  target/microblaze: Split out PC from env->sregs
  target/microblaze: Split out MSR from env->sregs
  target/microblaze: Split out EAR from env->sregs
  target/microblaze: Split out ESR from env->sregs
  target/microblaze: Split out FSR from env->sregs
  target/microblaze: Split out BTR from env->sregs
  target/microblaze: Split out EDR from env->sregs
  target/microblaze: Split the cpu_SR array
  target/microblaze: Fix width of PC and BTARGET
  target/microblaze: Fix width of MSR
  target/microblaze: Fix width of ESR
  target/microblaze: Fix width of FSR
  target/microblaze: Fix width of BTR
  target/microblaze: Fix width of EDR
  target/microblaze: Remove cpu_ear
  target/microblaze: Tidy raising of exceptions
  target/microblaze: Mark raise_exception as noreturn
  target/microblaze: Remove helper_debug and env->debug
  target/microblaze: Rename env_* tcg variables to cpu_*
  target/microblaze: Tidy mb_tcg_init
  target/microblaze: Split out MSR[C] to its own variable
  target/microblaze: Use DISAS_NORETURN
  target/microblaze: Check singlestep_enabled in gen_goto_tb
  target/microblaze: Convert to DisasContextBase
  target/microblaze: Convert to translator_loop
  target/microblaze: Remove SIM_COMPAT
  target/microblaze: Remove DISAS_GNU
  target/microblaze: Remove empty D macros
  target/microblaze: Remove LOG_DIS
  target/microblaze: Ensure imm constant is always available
  target/microblaze: Add decodetree infrastructure
  target/microblaze: Convert dec_add to decodetree
  target/microblaze: Convert dec_sub to decodetree
  target/microblaze: Implement cmp and cmpu inline
  target/microblaze: Convert dec_pattern to decodetree
  target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree
  target/microblaze: Convert dec_mul to decodetree
  target/microblaze: Convert dec_div to decodetree
  target/microblaze: Unwind properly when raising divide-by-zero
  target/microblaze: Convert dec_bit to decodetree
  target/microblaze: Convert dec_barrel to decodetree
  target/microblaze: Convert dec_imm to decodetree
  target/microblaze: Convert dec_fpu to decodetree
  target/microblaze: Fix cpu unwind for fpu exceptions
  target/microblaze: Mark fpu helpers TCG_CALL_NO_WG
  target/microblaze: Replace MSR_EE_FLAG with MSR_EE
  target/microblaze: Cache mem_index in DisasContext
  target/microblaze: Fix cpu unwind for stackprot
  target/microblaze: Convert dec_load and dec_store to decodetree
  target/microblaze: Assert no overlap in flags making up tb_flags
  target/microblaze: Move bimm to BIMM_FLAG
  target/microblaze: Fix no-op mb_cpu_transaction_failed
  target/microblaze: Store "current" iflags in insn_start
  tcg: Add tcg_get_insn_start_param
  target/microblaze: Use cc->do_unaligned_access
  target/microblaze: Replace clear_imm with tb_flags_to_set
  target/microblaze: Replace delayed_branch with tb_flags_to_set
  target/microblaze: Tidy mb_cpu_dump_state
  target/microblaze: Convert brk and brki to decodetree
  target/microblaze: Convert mbar to decodetree
  target/microblaze: Reorganize branching
  target/microblaze: Convert dec_br to decodetree
  target/microblaze: Convert dec_bcc to decodetree
  target/microblaze: Convert dec_rts to decodetree
  target/microblaze: Tidy do_rti, do_rtb, do_rte
  target/microblaze: Convert msrclr, msrset to decodetree
  target/microblaze: Convert dec_msr to decodetree
  target/microblaze: Convert dec_stream to decodetree
  target/microblaze: Remove last of old decoder
  target/microblaze: Remove cpu_R[0]
  target/microblaze: Add flags markup to some helpers
  target/microblaze: Reduce linux-user address space to 32-bit

 include/tcg/tcg.h                     |   15 +
 target/microblaze/cpu-param.h         |   15 +
 target/microblaze/cpu.h               |   67 +-
 target/microblaze/helper.h            |   49 +-
 target/microblaze/microblaze-decode.h |   59 -
 tests/tcg/multiarch/float_helpers.h   |   17 +
 target/microblaze/insns.decode        |  256 ++
 linux-user/elfload.c                  |    9 +-
 linux-user/microblaze/cpu_loop.c      |   26 +-
 linux-user/microblaze/signal.c        |    8 +-
 target/microblaze/cpu.c               |    9 +-
 target/microblaze/gdbstub.c           |  193 +-
 target/microblaze/helper.c            |  164 +-
 target/microblaze/mmu.c               |    4 +-
 target/microblaze/op_helper.c         |  194 +-
 target/microblaze/translate.c         | 3223 +++++++++++++------------
 tests/tcg/multiarch/float_convs.c     |    2 +
 tests/tcg/multiarch/float_madds.c     |    2 +
 target/microblaze/meson.build         |    3 +
 tests/tcg/configure.sh                |    2 +-
 20 files changed, 2292 insertions(+), 2025 deletions(-)
 delete mode 100644 target/microblaze/microblaze-decode.h
 create mode 100644 target/microblaze/insns.decode

-- 
2.25.1



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

* [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 17:32   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 02/76] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
                   ` (75 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Not attempting to use a single cross-compiler for both
big-endian and little-endian at this time.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tests/tcg/configure.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index 7d714f902a..598a50cd4f 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -94,7 +94,7 @@ for target in $target_list; do
     xtensa|xtensaeb)
       arches=xtensa
       ;;
-    alpha|cris|hppa|i386|lm32|m68k|openrisc|riscv64|s390x|sh4|sparc64)
+    alpha|cris|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64)
       arches=$target
       ;;
     *)
-- 
2.25.1



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

* [PATCH v2 02/76] tests/tcg: Do not require FE_TOWARDZERO
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 17:31   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 03/76] tests/tcg: Do not require FE_* exception bits Richard Henderson
                   ` (74 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This is optional in ISO C, and not all cpus provide it.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tests/tcg/multiarch/float_convs.c | 2 ++
 tests/tcg/multiarch/float_madds.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/tests/tcg/multiarch/float_convs.c b/tests/tcg/multiarch/float_convs.c
index 47e24b8b16..e9be75c2d5 100644
--- a/tests/tcg/multiarch/float_convs.c
+++ b/tests/tcg/multiarch/float_convs.c
@@ -30,7 +30,9 @@ float_mapping round_flags[] = {
 #ifdef FE_DOWNWARD
     { FE_DOWNWARD, "downwards" },
 #endif
+#ifdef FE_TOWARDZERO
     { FE_TOWARDZERO, "to zero" }
+#endif
 };
 
 static void print_input(float input)
diff --git a/tests/tcg/multiarch/float_madds.c b/tests/tcg/multiarch/float_madds.c
index eceb4ae38b..e422608ccd 100644
--- a/tests/tcg/multiarch/float_madds.c
+++ b/tests/tcg/multiarch/float_madds.c
@@ -29,7 +29,9 @@ float_mapping round_flags[] = {
 #ifdef FE_DOWNWARD
     { FE_DOWNWARD, "downwards" },
 #endif
+#ifdef FE_TOWARDZERO
     { FE_TOWARDZERO, "to zero" }
+#endif
 };
 
 
-- 
2.25.1



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

* [PATCH v2 03/76] tests/tcg: Do not require FE_* exception bits
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 02/76] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 17:30   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 04/76] target/microblaze: Tidy gdbstub Richard Henderson
                   ` (73 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Define anything that is missing as 0, so that flags & FE_FOO
is false for any missing FOO.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tests/tcg/multiarch/float_helpers.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tests/tcg/multiarch/float_helpers.h b/tests/tcg/multiarch/float_helpers.h
index 6337bc66c1..309f3f4bf1 100644
--- a/tests/tcg/multiarch/float_helpers.h
+++ b/tests/tcg/multiarch/float_helpers.h
@@ -8,6 +8,23 @@
 
 #include <inttypes.h>
 
+/* Some hosts do not have support for all of these; not required by ISO C. */
+#ifndef FE_OVERFLOW
+#define FE_OVERFLOW 0
+#endif
+#ifndef FE_UNDERFLOW
+#define FE_UNDERFLOW 0
+#endif
+#ifndef FE_DIVBYZERO
+#define FE_DIVBYZERO 0
+#endif
+#ifndef FE_INEXACT
+#define FE_INEXACT 0
+#endif
+#ifndef FE_INVALID
+#define FE_INVALID 0
+#endif
+
 /* Number of constants in each table */
 int get_num_f16(void);
 int get_num_f32(void);
-- 
2.25.1



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

* [PATCH v2 04/76] target/microblaze: Tidy gdbstub
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (2 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 03/76] tests/tcg: Do not require FE_* exception bits Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 05/76] target/microblaze: Split out PC from env->sregs Richard Henderson
                   ` (72 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Use an enumeration for the gdb register mapping.  Use one
switch statement for the entire dispatch.  Drop sreg_map
and simply enumerate those cases explicitly.  Force r0 to
have value 0 and ignore writes.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/gdbstub.c | 193 +++++++++++++++++++-----------------
 1 file changed, 101 insertions(+), 92 deletions(-)

diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 73e8973597..e65ec051a5 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -21,58 +21,80 @@
 #include "cpu.h"
 #include "exec/gdbstub.h"
 
+/*
+ * GDB expects SREGs in the following order:
+ * PC, MSR, EAR, ESR, FSR, BTR, EDR, PID, ZPR, TLBX, TLBSX, TLBLO, TLBHI.
+ *
+ * PID, ZPR, TLBx, TLBsx, TLBLO, and TLBHI aren't modeled, so we don't
+ * map them to anything and return a value of 0 instead.
+ */
+
+enum {
+    GDB_PC    = 32 + 0,
+    GDB_MSR   = 32 + 1,
+    GDB_EAR   = 32 + 2,
+    GDB_ESR   = 32 + 3,
+    GDB_FSR   = 32 + 4,
+    GDB_BTR   = 32 + 5,
+    GDB_PVR0  = 32 + 6,
+    GDB_PVR11 = 32 + 17,
+    GDB_EDR   = 32 + 18,
+    GDB_SLR   = 32 + 25,
+    GDB_SHR   = 32 + 26,
+};
+
 int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUClass *cc = CPU_GET_CLASS(cs);
     CPUMBState *env = &cpu->env;
-    /*
-     * GDB expects SREGs in the following order:
-     * PC, MSR, EAR, ESR, FSR, BTR, EDR, PID, ZPR, TLBX, TLBSX, TLBLO, TLBHI.
-     * They aren't stored in this order, so make a map.
-     * PID, ZPR, TLBx, TLBsx, TLBLO, and TLBHI aren't modeled, so we don't
-     * map them to anything and return a value of 0 instead.
-     */
-    static const uint8_t sreg_map[6] = {
-        SR_PC,
-        SR_MSR,
-        SR_EAR,
-        SR_ESR,
-        SR_FSR,
-        SR_BTR
-    };
+    uint32_t val;
 
-    /*
-     * GDB expects registers to be reported in this order:
-     * R0-R31
-     * PC-BTR
-     * PVR0-PVR11
-     * EDR-TLBHI
-     * SLR-SHR
-     */
-    if (n < 32) {
-        return gdb_get_reg32(mem_buf, env->regs[n]);
-    } else {
-        n -= 32;
-        switch (n) {
-        case 0 ... 5:
-            return gdb_get_reg32(mem_buf, env->sregs[sreg_map[n]]);
-        /* PVR12 is intentionally skipped */
-        case 6 ... 17:
-            n -= 6;
-            return gdb_get_reg32(mem_buf, env->pvr.regs[n]);
-        case 18:
-            return gdb_get_reg32(mem_buf, env->sregs[SR_EDR]);
-        /* Other SRegs aren't modeled, so report a value of 0 */
-        case 19 ... 24:
-            return gdb_get_reg32(mem_buf, 0);
-        case 25:
-            return gdb_get_reg32(mem_buf, env->slr);
-        case 26:
-            return gdb_get_reg32(mem_buf, env->shr);
-        default:
-            return 0;
-        }
+    if (n > cc->gdb_num_core_regs) {
+        return 0;
     }
+
+    switch (n) {
+    case 1 ... 31:
+        val = env->regs[n];
+        break;
+    case GDB_PC:
+        val = env->sregs[SR_PC];
+        break;
+    case GDB_MSR:
+        val = env->sregs[SR_MSR];
+        break;
+    case GDB_EAR:
+        val = env->sregs[SR_EAR];
+        break;
+    case GDB_ESR:
+        val = env->sregs[SR_ESR];
+        break;
+    case GDB_FSR:
+        val = env->sregs[SR_FSR];
+        break;
+    case GDB_BTR:
+        val = env->sregs[SR_BTR];
+        break;
+    case GDB_PVR0 ... GDB_PVR11:
+        /* PVR12 is intentionally skipped */
+        val = env->pvr.regs[n - GDB_PVR0];
+        break;
+    case GDB_EDR:
+        val = env->sregs[SR_EDR];
+        break;
+    case GDB_SLR:
+        val = env->slr;
+        break;
+    case GDB_SHR:
+        val = env->shr;
+        break;
+    default:
+        /* Other SRegs aren't modeled, so report a value of 0 */
+        val = 0;
+        break;
+    }
+    return gdb_get_reg32(mem_buf, val);
 }
 
 int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
@@ -82,60 +104,47 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
     CPUMBState *env = &cpu->env;
     uint32_t tmp;
 
-    /*
-     * GDB expects SREGs in the following order:
-     * PC, MSR, EAR, ESR, FSR, BTR, EDR, PID, ZPR, TLBX, TLBSX, TLBLO, TLBHI.
-     * They aren't stored in this order, so make a map.
-     * PID, ZPR, TLBx, TLBsx, TLBLO, and TLBHI aren't modeled, so we don't
-     * map them to anything.
-     */
-    static const uint8_t sreg_map[6] = {
-        SR_PC,
-        SR_MSR,
-        SR_EAR,
-        SR_ESR,
-        SR_FSR,
-        SR_BTR
-    };
-
     if (n > cc->gdb_num_core_regs) {
         return 0;
     }
 
     tmp = ldl_p(mem_buf);
 
-    /*
-     * GDB expects registers to be reported in this order:
-     * R0-R31
-     * PC-BTR
-     * PVR0-PVR11
-     * EDR-TLBHI
-     * SLR-SHR
-     */
-    if (n < 32) {
+    switch (n) {
+    case 1 ... 31:
         env->regs[n] = tmp;
-    } else {
-        n -= 32;
-        switch (n) {
-        case 0 ... 5:
-            env->sregs[sreg_map[n]] = tmp;
-            break;
+        break;
+    case GDB_PC:
+        env->sregs[SR_PC] = tmp;
+        break;
+    case GDB_MSR:
+        env->sregs[SR_MSR] = tmp;
+        break;
+    case GDB_EAR:
+        env->sregs[SR_EAR] = tmp;
+        break;
+    case GDB_ESR:
+        env->sregs[SR_ESR] = tmp;
+        break;
+    case GDB_FSR:
+        env->sregs[SR_FSR] = tmp;
+        break;
+    case GDB_BTR:
+        env->sregs[SR_BTR] = tmp;
+        break;
+    case GDB_PVR0 ... GDB_PVR11:
         /* PVR12 is intentionally skipped */
-        case 6 ... 17:
-            n -= 6;
-            env->pvr.regs[n] = tmp;
-            break;
-        /* Only EDR is modeled in these indeces, so ignore the rest */
-        case 18:
-            env->sregs[SR_EDR] = tmp;
-            break;
-        case 25:
-            env->slr = tmp;
-            break;
-        case 26:
-            env->shr = tmp;
-            break;
-        }
+        env->pvr.regs[n - GDB_PVR0] = tmp;
+        break;
+    case GDB_EDR:
+        env->sregs[SR_EDR] = tmp;
+        break;
+    case GDB_SLR:
+        env->slr = tmp;
+        break;
+    case GDB_SHR:
+        env->shr = tmp;
+        break;
     }
     return 4;
 }
-- 
2.25.1



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

* [PATCH v2 05/76] target/microblaze: Split out PC from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (3 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 04/76] target/microblaze: Tidy gdbstub Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 06/76] target/microblaze: Split out MSR " Richard Henderson
                   ` (71 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Begin eliminating the sregs array in favor of individual members.
Does not correct the width of pc, yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h          |  3 ++-
 linux-user/microblaze/cpu_loop.c | 12 +++++------
 linux-user/microblaze/signal.c   |  8 ++++----
 target/microblaze/cpu.c          |  4 ++--
 target/microblaze/gdbstub.c      |  4 ++--
 target/microblaze/helper.c       | 34 ++++++++++++++++----------------
 target/microblaze/mmu.c          |  2 +-
 target/microblaze/op_helper.c    |  2 +-
 target/microblaze/translate.c    | 10 +++++++---
 9 files changed, 42 insertions(+), 37 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a31134b65c..d1f91bb318 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -236,6 +236,7 @@ struct CPUMBState {
 
     uint32_t imm;
     uint32_t regs[32];
+    uint64_t pc;
     uint64_t sregs[14];
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
@@ -351,7 +352,7 @@ typedef MicroBlazeCPU ArchCPU;
 static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
-    *pc = env->sregs[SR_PC];
+    *pc = env->pc;
     *cs_base = 0;
     *flags = (env->iflags & IFLAGS_TB_MASK) |
                  (env->sregs[SR_MSR] & (MSR_UM | MSR_VM | MSR_EE));
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 3e0a7f730b..3c693086f4 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -51,7 +51,7 @@ void cpu_loop(CPUMBState *env)
         case EXCP_BREAK:
             /* Return address is 4 bytes after the call.  */
             env->regs[14] += 4;
-            env->sregs[SR_PC] = env->regs[14];
+            env->pc = env->regs[14];
             ret = do_syscall(env, 
                              env->regs[12], 
                              env->regs[5], 
@@ -63,7 +63,7 @@ void cpu_loop(CPUMBState *env)
                              0, 0);
             if (ret == -TARGET_ERESTARTSYS) {
                 /* Wind back to before the syscall. */
-                env->sregs[SR_PC] -= 4;
+                env->pc -= 4;
             } else if (ret != -TARGET_QEMU_ESIGRETURN) {
                 env->regs[3] = ret;
             }
@@ -73,13 +73,13 @@ void cpu_loop(CPUMBState *env)
              * not a userspace-usable register, as the kernel may clobber it
              * at any point.)
              */
-            env->regs[14] = env->sregs[SR_PC];
+            env->regs[14] = env->pc;
             break;
         case EXCP_HW_EXCP:
-            env->regs[17] = env->sregs[SR_PC] + 4;
+            env->regs[17] = env->pc + 4;
             if (env->iflags & D_FLAG) {
                 env->sregs[SR_ESR] |= 1 << 12;
-                env->sregs[SR_PC] -= 4;
+                env->pc -= 4;
                 /* FIXME: if branch was immed, replay the imm as well.  */
             }
 
@@ -165,5 +165,5 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
     env->regs[29] = regs->r29;
     env->regs[30] = regs->r30;
     env->regs[31] = regs->r31;
-    env->sregs[SR_PC] = regs->pc;
+    env->pc = regs->pc;
 }
diff --git a/linux-user/microblaze/signal.c b/linux-user/microblaze/signal.c
index 80950c2181..b4eeef4673 100644
--- a/linux-user/microblaze/signal.c
+++ b/linux-user/microblaze/signal.c
@@ -87,7 +87,7 @@ static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
     __put_user(env->regs[29], &sc->regs.r29);
     __put_user(env->regs[30], &sc->regs.r30);
     __put_user(env->regs[31], &sc->regs.r31);
-    __put_user(env->sregs[SR_PC], &sc->regs.pc);
+    __put_user(env->pc, &sc->regs.pc);
 }
 
 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
@@ -124,7 +124,7 @@ static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
     __get_user(env->regs[29], &sc->regs.r29);
     __get_user(env->regs[30], &sc->regs.r30);
     __get_user(env->regs[31], &sc->regs.r31);
-    __get_user(env->sregs[SR_PC], &sc->regs.pc);
+    __get_user(env->pc, &sc->regs.pc);
 }
 
 static abi_ulong get_sigframe(struct target_sigaction *ka,
@@ -188,7 +188,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
     env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
 
     /* Offset of 4 to handle microblaze rtid r14, 0 */
-    env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
+    env->pc = (unsigned long)ka->_sa_handler;
 
     unlock_user_struct(frame, frame_addr, 1);
     return;
@@ -228,7 +228,7 @@ long do_sigreturn(CPUMBState *env)
     restore_sigcontext(&frame->uc.tuc_mcontext, env);
     /* We got here through a sigreturn syscall, our path back is via an
        rtb insn so setup r14 for that.  */
-    env->regs[14] = env->sregs[SR_PC];
+    env->regs[14] = env->pc;
 
     unlock_user_struct(frame, frame_addr, 0);
     return -TARGET_QEMU_ESIGRETURN;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 51e5c85b10..bde9992535 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -79,7 +79,7 @@ static void mb_cpu_set_pc(CPUState *cs, vaddr value)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
 
-    cpu->env.sregs[SR_PC] = value;
+    cpu->env.pc = value;
 }
 
 static bool mb_cpu_has_work(CPUState *cs)
@@ -117,7 +117,7 @@ static void mb_cpu_reset(DeviceState *dev)
     /* Disable stack protector.  */
     env->shr = ~0;
 
-    env->sregs[SR_PC] = cpu->cfg.base_vectors;
+    env->pc = cpu->cfg.base_vectors;
 
 #if defined(CONFIG_USER_ONLY)
     /* start in user mode with interrupts enabled.  */
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index e65ec051a5..9ea31f8d2f 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -59,7 +59,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->regs[n];
         break;
     case GDB_PC:
-        val = env->sregs[SR_PC];
+        val = env->pc;
         break;
     case GDB_MSR:
         val = env->sregs[SR_MSR];
@@ -115,7 +115,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->regs[n] = tmp;
         break;
     case GDB_PC:
-        env->sregs[SR_PC] = tmp;
+        env->pc = tmp;
         break;
     case GDB_MSR:
         env->sregs[SR_MSR] = tmp;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index ab2ceeb055..5c392deea4 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -35,7 +35,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
 
     cs->exception_index = -1;
     env->res_addr = RES_ADDR_NONE;
-    env->regs[14] = env->sregs[SR_PC];
+    env->regs[14] = env->pc;
 }
 
 bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -126,7 +126,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                 return;
             }
 
-            env->regs[17] = env->sregs[SR_PC] + 4;
+            env->regs[17] = env->pc + 4;
             env->sregs[SR_ESR] &= ~(1 << 12);
 
             /* Exception breaks branch + dslot sequence?  */
@@ -145,15 +145,15 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                           "hw exception at pc=%" PRIx64 " ear=%" PRIx64 " "
                           "esr=%" PRIx64 " iflags=%x\n",
-                          env->sregs[SR_PC], env->sregs[SR_EAR],
+                          env->pc, env->sregs[SR_EAR],
                           env->sregs[SR_ESR], env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
-            env->sregs[SR_PC] = cpu->cfg.base_vectors + 0x20;
+            env->pc = cpu->cfg.base_vectors + 0x20;
             break;
 
         case EXCP_MMU:
-            env->regs[17] = env->sregs[SR_PC];
+            env->regs[17] = env->pc;
 
             env->sregs[SR_ESR] &= ~(1 << 12);
             /* Exception breaks branch + dslot sequence?  */
@@ -169,7 +169,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                     qemu_log_mask(CPU_LOG_INT,
                                   "bimm exception at pc=%" PRIx64 " "
                                   "iflags=%x\n",
-                                  env->sregs[SR_PC], env->iflags);
+                                  env->pc, env->iflags);
                     env->regs[17] -= 4;
                     log_cpu_state_mask(CPU_LOG_INT, cs, 0);
                 }
@@ -188,10 +188,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                           "exception at pc=%" PRIx64 " ear=%" PRIx64 " "
                           "iflags=%x\n",
-                          env->sregs[SR_PC], env->sregs[SR_EAR], env->iflags);
+                          env->pc, env->sregs[SR_EAR], env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
-            env->sregs[SR_PC] = cpu->cfg.base_vectors + 0x20;
+            env->pc = cpu->cfg.base_vectors + 0x20;
             break;
 
         case EXCP_IRQ:
@@ -209,14 +209,14 @@ void mb_cpu_do_interrupt(CPUState *cs)
             {
                 const char *sym;
 
-                sym = lookup_symbol(env->sregs[SR_PC]);
+                sym = lookup_symbol(env->pc);
                 if (sym
                     && (!strcmp("netif_rx", sym)
                         || !strcmp("process_backlog", sym))) {
 
                     qemu_log(
                          "interrupt at pc=%x msr=%x %x iflags=%x sym=%s\n",
-                         env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags,
+                         env->pc, env->sregs[SR_MSR], t, env->iflags,
                          sym);
 
                     log_cpu_state(cs, 0);
@@ -226,14 +226,14 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                          "interrupt at pc=%" PRIx64 " msr=%" PRIx64 " %x "
                          "iflags=%x\n",
-                         env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);
+                         env->pc, env->sregs[SR_MSR], t, env->iflags);
 
             env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM \
                                     | MSR_UM | MSR_IE);
             env->sregs[SR_MSR] |= t;
 
-            env->regs[14] = env->sregs[SR_PC];
-            env->sregs[SR_PC] = cpu->cfg.base_vectors + 0x10;
+            env->regs[14] = env->pc;
+            env->pc = cpu->cfg.base_vectors + 0x10;
             //log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             break;
 
@@ -245,17 +245,17 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                         "break at pc=%" PRIx64 " msr=%" PRIx64 " %x "
                         "iflags=%x\n",
-                        env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);
+                        env->pc, env->sregs[SR_MSR], t, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             env->sregs[SR_MSR] |= t;
             env->sregs[SR_MSR] |= MSR_BIP;
             if (cs->exception_index == EXCP_HW_BREAK) {
-                env->regs[16] = env->sregs[SR_PC];
+                env->regs[16] = env->pc;
                 env->sregs[SR_MSR] |= MSR_BIP;
-                env->sregs[SR_PC] = cpu->cfg.base_vectors + 0x18;
+                env->pc = cpu->cfg.base_vectors + 0x18;
             } else
-                env->sregs[SR_PC] = env->btarget;
+                env->pc = env->btarget;
             break;
         default:
             cpu_abort(cs, "unhandled exception type=%d\n",
diff --git a/target/microblaze/mmu.c b/target/microblaze/mmu.c
index 6763421ba2..3f403b567b 100644
--- a/target/microblaze/mmu.c
+++ b/target/microblaze/mmu.c
@@ -251,7 +251,7 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
                 if (i < 3 && !(v & TLB_VALID) && qemu_loglevel_mask(~0))
                     qemu_log_mask(LOG_GUEST_ERROR,
                              "invalidating index %x at pc=%" PRIx64 "\n",
-                             i, env->sregs[SR_PC]);
+                             i, env->pc);
                 env->mmu.tids[i] = env->mmu.regs[MMU_R_PID] & 0xff;
                 mmu_flush_idx(env, i);
             }
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index f3b17a95b3..2deef32740 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -75,7 +75,7 @@ void helper_debug(CPUMBState *env)
 {
     int i;
 
-    qemu_log("PC=%" PRIx64 "\n", env->sregs[SR_PC]);
+    qemu_log("PC=%" PRIx64 "\n", env->pc);
     qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
              env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a96cb21d96..9f6815cc1f 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1805,7 +1805,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     }
 
     qemu_fprintf(f, "IN: PC=%" PRIx64 " %s\n",
-                 env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
+                 env->pc, lookup_symbol(env->pc));
     qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
@@ -1868,7 +1868,11 @@ void mb_tcg_init(void)
                           offsetof(CPUMBState, regs[i]),
                           regnames[i]);
     }
-    for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
+
+    cpu_SR[SR_PC] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, pc), "rpc");
+
+    for (i = 1; i < ARRAY_SIZE(cpu_SR); i++) {
         cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
@@ -1878,5 +1882,5 @@ void mb_tcg_init(void)
 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
-    env->sregs[SR_PC] = data[0];
+    env->pc = data[0];
 }
-- 
2.25.1



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

* [PATCH v2 06/76] target/microblaze: Split out MSR from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (4 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 05/76] target/microblaze: Split out PC from env->sregs Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 07/76] target/microblaze: Split out EAR " Richard Henderson
                   ` (70 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Continue eliminating the sregs array in favor of individual members.
Does not correct the width of MSR, yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  7 ++---
 target/microblaze/cpu.c       |  4 +--
 target/microblaze/gdbstub.c   |  4 +--
 target/microblaze/helper.c    | 49 +++++++++++++++++------------------
 target/microblaze/op_helper.c | 22 ++++++++--------
 target/microblaze/translate.c | 14 +++++-----
 6 files changed, 51 insertions(+), 49 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index d1f91bb318..36de61d9f9 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -237,6 +237,7 @@ struct CPUMBState {
     uint32_t imm;
     uint32_t regs[32];
     uint64_t pc;
+    uint64_t msr;
     uint64_t sregs[14];
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
@@ -355,7 +356,7 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
     *pc = env->pc;
     *cs_base = 0;
     *flags = (env->iflags & IFLAGS_TB_MASK) |
-                 (env->sregs[SR_MSR] & (MSR_UM | MSR_VM | MSR_EE));
+             (env->msr & (MSR_UM | MSR_VM | MSR_EE));
 }
 
 #if !defined(CONFIG_USER_ONLY)
@@ -370,11 +371,11 @@ static inline int cpu_mmu_index(CPUMBState *env, bool ifetch)
     MicroBlazeCPU *cpu = env_archcpu(env);
 
     /* Are we in nommu mode?.  */
-    if (!(env->sregs[SR_MSR] & MSR_VM) || !cpu->cfg.use_mmu) {
+    if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
         return MMU_NOMMU_IDX;
     }
 
-    if (env->sregs[SR_MSR] & MSR_UM) {
+    if (env->msr & MSR_UM) {
         return MMU_USER_IDX;
     }
     return MMU_KERNEL_IDX;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index bde9992535..0eac068570 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -121,9 +121,9 @@ static void mb_cpu_reset(DeviceState *dev)
 
 #if defined(CONFIG_USER_ONLY)
     /* start in user mode with interrupts enabled.  */
-    env->sregs[SR_MSR] = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
+    env->msr = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
 #else
-    env->sregs[SR_MSR] = 0;
+    env->msr = 0;
     mmu_init(&env->mmu);
     env->mmu.c_mmu = 3;
     env->mmu.c_mmu_tlb_access = 3;
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 9ea31f8d2f..e4c4936a7a 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -62,7 +62,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->pc;
         break;
     case GDB_MSR:
-        val = env->sregs[SR_MSR];
+        val = env->msr;
         break;
     case GDB_EAR:
         val = env->sregs[SR_EAR];
@@ -118,7 +118,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->pc = tmp;
         break;
     case GDB_MSR:
-        env->sregs[SR_MSR] = tmp;
+        env->msr = tmp;
         break;
     case GDB_EAR:
         env->sregs[SR_EAR] = tmp;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 5c392deea4..a18314540f 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -117,7 +117,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
     /* IMM flag cannot propagate across a branch and into the dslot.  */
     assert(!((env->iflags & D_FLAG) && (env->iflags & IMM_FLAG)));
     assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
-/*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
+/*    assert(env->msr & (MSR_EE)); Only for HW exceptions.  */
     env->res_addr = RES_ADDR_NONE;
     switch (cs->exception_index) {
         case EXCP_HW_EXCP:
@@ -136,11 +136,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 
             /* Disable the MMU.  */
-            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
-            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
-            env->sregs[SR_MSR] |= t;
+            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
+            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+            env->msr |= t;
             /* Exception in progress.  */
-            env->sregs[SR_MSR] |= MSR_EIP;
+            env->msr |= MSR_EIP;
 
             qemu_log_mask(CPU_LOG_INT,
                           "hw exception at pc=%" PRIx64 " ear=%" PRIx64 " "
@@ -179,11 +179,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 
             /* Disable the MMU.  */
-            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
-            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
-            env->sregs[SR_MSR] |= t;
+            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
+            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+            env->msr |= t;
             /* Exception in progress.  */
-            env->sregs[SR_MSR] |= MSR_EIP;
+            env->msr |= MSR_EIP;
 
             qemu_log_mask(CPU_LOG_INT,
                           "exception at pc=%" PRIx64 " ear=%" PRIx64 " "
@@ -195,11 +195,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
             break;
 
         case EXCP_IRQ:
-            assert(!(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)));
-            assert(env->sregs[SR_MSR] & MSR_IE);
+            assert(!(env->msr & (MSR_EIP | MSR_BIP)));
+            assert(env->msr & MSR_IE);
             assert(!(env->iflags & D_FLAG));
 
-            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
+            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
 
 #if 0
 #include "disas/disas.h"
@@ -216,7 +216,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
 
                     qemu_log(
                          "interrupt at pc=%x msr=%x %x iflags=%x sym=%s\n",
-                         env->pc, env->sregs[SR_MSR], t, env->iflags,
+                         env->pc, env->msr, t, env->iflags,
                          sym);
 
                     log_cpu_state(cs, 0);
@@ -226,11 +226,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                          "interrupt at pc=%" PRIx64 " msr=%" PRIx64 " %x "
                          "iflags=%x\n",
-                         env->pc, env->sregs[SR_MSR], t, env->iflags);
+                         env->pc, env->msr, t, env->iflags);
 
-            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM \
-                                    | MSR_UM | MSR_IE);
-            env->sregs[SR_MSR] |= t;
+            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE);
+            env->msr |= t;
 
             env->regs[14] = env->pc;
             env->pc = cpu->cfg.base_vectors + 0x10;
@@ -241,18 +240,18 @@ void mb_cpu_do_interrupt(CPUState *cs)
         case EXCP_HW_BREAK:
             assert(!(env->iflags & IMM_FLAG));
             assert(!(env->iflags & D_FLAG));
-            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
+            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
             qemu_log_mask(CPU_LOG_INT,
                         "break at pc=%" PRIx64 " msr=%" PRIx64 " %x "
                         "iflags=%x\n",
-                        env->pc, env->sregs[SR_MSR], t, env->iflags);
+                        env->pc, env->msr, t, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
-            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
-            env->sregs[SR_MSR] |= t;
-            env->sregs[SR_MSR] |= MSR_BIP;
+            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+            env->msr |= t;
+            env->msr |= MSR_BIP;
             if (cs->exception_index == EXCP_HW_BREAK) {
                 env->regs[16] = env->pc;
-                env->sregs[SR_MSR] |= MSR_BIP;
+                env->msr |= MSR_BIP;
                 env->pc = cpu->cfg.base_vectors + 0x18;
             } else
                 env->pc = env->btarget;
@@ -293,8 +292,8 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     CPUMBState *env = &cpu->env;
 
     if ((interrupt_request & CPU_INTERRUPT_HARD)
-        && (env->sregs[SR_MSR] & MSR_IE)
-        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
+        && (env->msr & MSR_IE)
+        && !(env->msr & (MSR_EIP | MSR_BIP))
         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
         cs->exception_index = EXCP_IRQ;
         mb_cpu_do_interrupt(cs);
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 2deef32740..3668382d36 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -78,14 +78,14 @@ void helper_debug(CPUMBState *env)
     qemu_log("PC=%" PRIx64 "\n", env->pc);
     qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
-             env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
+             env->msr, env->sregs[SR_ESR], env->sregs[SR_EAR],
              env->debug, env->imm, env->iflags);
     qemu_log("btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) eip=%d ie=%d\n",
              env->btaken, env->btarget,
-             (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
-             (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
-             (bool)(env->sregs[SR_MSR] & MSR_EIP),
-             (bool)(env->sregs[SR_MSR] & MSR_IE));
+             (env->msr & MSR_UM) ? "user" : "kernel",
+             (env->msr & MSR_UMS) ? "user" : "kernel",
+             (bool)(env->msr & MSR_EIP),
+             (bool)(env->msr & MSR_IE));
     for (i = 0; i < 32; i++) {
         qemu_log("r%2.2d=%8.8x ", i, env->regs[i]);
         if ((i + 1) % 4 == 0)
@@ -135,15 +135,15 @@ static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
     MicroBlazeCPU *cpu = env_archcpu(env);
 
     if (b == 0) {
-        env->sregs[SR_MSR] |= MSR_DZ;
+        env->msr |= MSR_DZ;
 
-        if ((env->sregs[SR_MSR] & MSR_EE) && cpu->cfg.div_zero_exception) {
+        if ((env->msr & MSR_EE) && cpu->cfg.div_zero_exception) {
             env->sregs[SR_ESR] = ESR_EC_DIVZERO;
             helper_raise_exception(env, EXCP_HW_EXCP);
         }
         return 0;
     }
-    env->sregs[SR_MSR] &= ~MSR_DZ;
+    env->msr &= ~MSR_DZ;
     return 1;
 }
 
@@ -192,7 +192,7 @@ static void update_fpu_flags(CPUMBState *env, int flags)
     }
     if (raise
         && (env->pvr.regs[2] & PVR2_FPU_EXC_MASK)
-        && (env->sregs[SR_MSR] & MSR_EE)) {
+        && (env->msr & MSR_EE)) {
         raise_fpu_exception(env);
     }
 }
@@ -437,7 +437,7 @@ void helper_memalign(CPUMBState *env, target_ulong addr,
             if (mask == 3) {
                 env->sregs[SR_ESR] |= 1 << 11;
             }
-            if (!(env->sregs[SR_MSR] & MSR_EE)) {
+            if (!(env->msr & MSR_EE)) {
                 return;
             }
             helper_raise_exception(env, EXCP_HW_EXCP);
@@ -484,7 +484,7 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
     env = &cpu->env;
 
     cpu_restore_state(cs, retaddr, true);
-    if (!(env->sregs[SR_MSR] & MSR_EE)) {
+    if (!(env->msr & MSR_EE)) {
         return;
     }
 
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9f6815cc1f..9f2dcd82cd 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1809,16 +1809,16 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
-                 env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
+                 env->msr, env->sregs[SR_ESR], env->sregs[SR_EAR],
                  env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
                  env->sregs[SR_BTR]);
     qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
                  "eip=%d ie=%d\n",
                  env->btaken, env->btarget,
-                 (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
-                 (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
-                 (bool)(env->sregs[SR_MSR] & MSR_EIP),
-                 (bool)(env->sregs[SR_MSR] & MSR_IE));
+                 (env->msr & MSR_UM) ? "user" : "kernel",
+                 (env->msr & MSR_UMS) ? "user" : "kernel",
+                 (bool)(env->msr & MSR_EIP),
+                 (bool)(env->msr & MSR_IE));
     for (i = 0; i < 12; i++) {
         qemu_fprintf(f, "rpvr%2.2d=%8.8x ", i, env->pvr.regs[i]);
         if ((i + 1) % 4 == 0) {
@@ -1871,8 +1871,10 @@ void mb_tcg_init(void)
 
     cpu_SR[SR_PC] =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, pc), "rpc");
+    cpu_SR[SR_MSR] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr), "rmsr");
 
-    for (i = 1; i < ARRAY_SIZE(cpu_SR); i++) {
+    for (i = SR_MSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
         cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
-- 
2.25.1



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

* [PATCH v2 07/76] target/microblaze: Split out EAR from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (5 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 06/76] target/microblaze: Split out MSR " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 20:50   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 08/76] target/microblaze: Split out ESR " Richard Henderson
                   ` (69 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Continue eliminating the sregs array in favor of individual members.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       | 1 +
 target/microblaze/gdbstub.c   | 4 ++--
 target/microblaze/helper.c    | 6 +++---
 target/microblaze/op_helper.c | 8 ++++----
 target/microblaze/translate.c | 6 ++++--
 5 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 36de61d9f9..c9035b410e 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -238,6 +238,7 @@ struct CPUMBState {
     uint32_t regs[32];
     uint64_t pc;
     uint64_t msr;
+    uint64_t ear;
     uint64_t sregs[14];
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index e4c4936a7a..e33a613efe 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -65,7 +65,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->msr;
         break;
     case GDB_EAR:
-        val = env->sregs[SR_EAR];
+        val = env->ear;
         break;
     case GDB_ESR:
         val = env->sregs[SR_ESR];
@@ -121,7 +121,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->msr = tmp;
         break;
     case GDB_EAR:
-        env->sregs[SR_EAR] = tmp;
+        env->ear = tmp;
         break;
     case GDB_ESR:
         env->sregs[SR_ESR] = tmp;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index a18314540f..afe9634781 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -85,7 +85,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     qemu_log_mask(CPU_LOG_MMU, "mmu=%d miss v=%" VADDR_PRIx "\n",
                   mmu_idx, address);
 
-    env->sregs[SR_EAR] = address;
+    env->ear = address;
     switch (lu.err) {
     case ERR_PROT:
         env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? 17 : 16;
@@ -145,7 +145,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                           "hw exception at pc=%" PRIx64 " ear=%" PRIx64 " "
                           "esr=%" PRIx64 " iflags=%x\n",
-                          env->pc, env->sregs[SR_EAR],
+                          env->pc, env->ear,
                           env->sregs[SR_ESR], env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
@@ -188,7 +188,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                           "exception at pc=%" PRIx64 " ear=%" PRIx64 " "
                           "iflags=%x\n",
-                          env->pc, env->sregs[SR_EAR], env->iflags);
+                          env->pc, env->ear, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
             env->pc = cpu->cfg.base_vectors + 0x20;
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 3668382d36..5bacd29663 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -78,7 +78,7 @@ void helper_debug(CPUMBState *env)
     qemu_log("PC=%" PRIx64 "\n", env->pc);
     qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
-             env->msr, env->sregs[SR_ESR], env->sregs[SR_EAR],
+             env->msr, env->sregs[SR_ESR], env->ear,
              env->debug, env->imm, env->iflags);
     qemu_log("btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) eip=%d ie=%d\n",
              env->btaken, env->btarget,
@@ -431,7 +431,7 @@ void helper_memalign(CPUMBState *env, target_ulong addr,
                           "unaligned access addr=" TARGET_FMT_lx
                           " mask=%x, wr=%d dr=r%d\n",
                           addr, mask, wr, dr);
-            env->sregs[SR_EAR] = addr;
+            env->ear = addr;
             env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \
                                  | (dr & 31) << 5;
             if (mask == 3) {
@@ -450,7 +450,7 @@ void helper_stackprot(CPUMBState *env, target_ulong addr)
         qemu_log_mask(CPU_LOG_INT, "Stack protector violation at "
                       TARGET_FMT_lx " %x %x\n",
                       addr, env->slr, env->shr);
-        env->sregs[SR_EAR] = addr;
+        env->ear = addr;
         env->sregs[SR_ESR] = ESR_EC_STACKPROT;
         helper_raise_exception(env, EXCP_HW_EXCP);
     }
@@ -488,7 +488,7 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
         return;
     }
 
-    env->sregs[SR_EAR] = addr;
+    env->ear = addr;
     if (access_type == MMU_INST_FETCH) {
         if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
             env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9f2dcd82cd..62747b02f3 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1809,7 +1809,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
-                 env->msr, env->sregs[SR_ESR], env->sregs[SR_EAR],
+                 env->msr, env->sregs[SR_ESR], env->ear,
                  env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
                  env->sregs[SR_BTR]);
     qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
@@ -1873,8 +1873,10 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, pc), "rpc");
     cpu_SR[SR_MSR] =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr), "rmsr");
+    cpu_SR[SR_EAR] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
 
-    for (i = SR_MSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
+    for (i = SR_EAR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
         cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
-- 
2.25.1



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

* [PATCH v2 08/76] target/microblaze: Split out ESR from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (6 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 07/76] target/microblaze: Split out EAR " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 09/76] target/microblaze: Split out FSR " Richard Henderson
                   ` (68 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Continue eliminating the sregs array in favor of individual members.
Does not correct the width of ESR, yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h          |  1 +
 linux-user/microblaze/cpu_loop.c |  6 +++---
 target/microblaze/gdbstub.c      |  4 ++--
 target/microblaze/helper.c       | 18 +++++++++---------
 target/microblaze/op_helper.c    | 17 ++++++++---------
 target/microblaze/translate.c    |  6 ++++--
 6 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index c9035b410e..7d94af43ed 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -239,6 +239,7 @@ struct CPUMBState {
     uint64_t pc;
     uint64_t msr;
     uint64_t ear;
+    uint64_t esr;
     uint64_t sregs[14];
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 3c693086f4..c10e3e0261 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -78,14 +78,14 @@ void cpu_loop(CPUMBState *env)
         case EXCP_HW_EXCP:
             env->regs[17] = env->pc + 4;
             if (env->iflags & D_FLAG) {
-                env->sregs[SR_ESR] |= 1 << 12;
+                env->esr |= 1 << 12;
                 env->pc -= 4;
                 /* FIXME: if branch was immed, replay the imm as well.  */
             }
 
             env->iflags &= ~(IMM_FLAG | D_FLAG);
 
-            switch (env->sregs[SR_ESR] & 31) {
+            switch (env->esr & 31) {
                 case ESR_EC_DIVZERO:
                     info.si_signo = TARGET_SIGFPE;
                     info.si_errno = 0;
@@ -107,7 +107,7 @@ void cpu_loop(CPUMBState *env)
                     break;
                 default:
                     fprintf(stderr, "Unhandled hw-exception: 0x%" PRIx64 "\n",
-                            env->sregs[SR_ESR] & ESR_EC_MASK);
+                            env->esr & ESR_EC_MASK);
                     cpu_dump_state(cs, stderr, 0);
                     exit(EXIT_FAILURE);
                     break;
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index e33a613efe..05e22f233d 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -68,7 +68,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->ear;
         break;
     case GDB_ESR:
-        val = env->sregs[SR_ESR];
+        val = env->esr;
         break;
     case GDB_FSR:
         val = env->sregs[SR_FSR];
@@ -124,7 +124,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->ear = tmp;
         break;
     case GDB_ESR:
-        env->sregs[SR_ESR] = tmp;
+        env->esr = tmp;
         break;
     case GDB_FSR:
         env->sregs[SR_FSR] = tmp;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index afe9634781..ea290be780 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -88,12 +88,12 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     env->ear = address;
     switch (lu.err) {
     case ERR_PROT:
-        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? 17 : 16;
-        env->sregs[SR_ESR] |= (access_type == MMU_DATA_STORE) << 10;
+        env->esr = access_type == MMU_INST_FETCH ? 17 : 16;
+        env->esr |= (access_type == MMU_DATA_STORE) << 10;
         break;
     case ERR_MISS:
-        env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? 19 : 18;
-        env->sregs[SR_ESR] |= (access_type == MMU_DATA_STORE) << 10;
+        env->esr = access_type == MMU_INST_FETCH ? 19 : 18;
+        env->esr |= (access_type == MMU_DATA_STORE) << 10;
         break;
     default:
         abort();
@@ -127,11 +127,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 
             env->regs[17] = env->pc + 4;
-            env->sregs[SR_ESR] &= ~(1 << 12);
+            env->esr &= ~(1 << 12);
 
             /* Exception breaks branch + dslot sequence?  */
             if (env->iflags & D_FLAG) {
-                env->sregs[SR_ESR] |= 1 << 12 ;
+                env->esr |= 1 << 12 ;
                 env->sregs[SR_BTR] = env->btarget;
             }
 
@@ -146,7 +146,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                           "hw exception at pc=%" PRIx64 " ear=%" PRIx64 " "
                           "esr=%" PRIx64 " iflags=%x\n",
                           env->pc, env->ear,
-                          env->sregs[SR_ESR], env->iflags);
+                          env->esr, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
             env->pc = cpu->cfg.base_vectors + 0x20;
@@ -155,11 +155,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
         case EXCP_MMU:
             env->regs[17] = env->pc;
 
-            env->sregs[SR_ESR] &= ~(1 << 12);
+            env->esr &= ~(1 << 12);
             /* Exception breaks branch + dslot sequence?  */
             if (env->iflags & D_FLAG) {
                 D(qemu_log("D_FLAG set at exception bimm=%d\n", env->bimm));
-                env->sregs[SR_ESR] |= 1 << 12 ;
+                env->esr |= 1 << 12 ;
                 env->sregs[SR_BTR] = env->btarget;
 
                 /* Reexecute the branch.  */
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 5bacd29663..f01cf9be64 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -78,7 +78,7 @@ void helper_debug(CPUMBState *env)
     qemu_log("PC=%" PRIx64 "\n", env->pc);
     qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
-             env->msr, env->sregs[SR_ESR], env->ear,
+             env->msr, env->esr, env->ear,
              env->debug, env->imm, env->iflags);
     qemu_log("btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) eip=%d ie=%d\n",
              env->btaken, env->btarget,
@@ -138,7 +138,7 @@ static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
         env->msr |= MSR_DZ;
 
         if ((env->msr & MSR_EE) && cpu->cfg.div_zero_exception) {
-            env->sregs[SR_ESR] = ESR_EC_DIVZERO;
+            env->esr = ESR_EC_DIVZERO;
             helper_raise_exception(env, EXCP_HW_EXCP);
         }
         return 0;
@@ -166,7 +166,7 @@ uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
 /* raise FPU exception.  */
 static void raise_fpu_exception(CPUMBState *env)
 {
-    env->sregs[SR_ESR] = ESR_EC_FPU;
+    env->esr = ESR_EC_FPU;
     helper_raise_exception(env, EXCP_HW_EXCP);
 }
 
@@ -432,10 +432,9 @@ void helper_memalign(CPUMBState *env, target_ulong addr,
                           " mask=%x, wr=%d dr=r%d\n",
                           addr, mask, wr, dr);
             env->ear = addr;
-            env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \
-                                 | (dr & 31) << 5;
+            env->esr = ESR_EC_UNALIGNED_DATA | (wr << 10) | (dr & 31) << 5;
             if (mask == 3) {
-                env->sregs[SR_ESR] |= 1 << 11;
+                env->esr |= 1 << 11;
             }
             if (!(env->msr & MSR_EE)) {
                 return;
@@ -451,7 +450,7 @@ void helper_stackprot(CPUMBState *env, target_ulong addr)
                       TARGET_FMT_lx " %x %x\n",
                       addr, env->slr, env->shr);
         env->ear = addr;
-        env->sregs[SR_ESR] = ESR_EC_STACKPROT;
+        env->esr = ESR_EC_STACKPROT;
         helper_raise_exception(env, EXCP_HW_EXCP);
     }
 }
@@ -491,12 +490,12 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
     env->ear = addr;
     if (access_type == MMU_INST_FETCH) {
         if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
-            env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
+            env->esr = ESR_EC_INSN_BUS;
             helper_raise_exception(env, EXCP_HW_EXCP);
         }
     } else {
         if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
-            env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
+            env->esr = ESR_EC_DATA_BUS;
             helper_raise_exception(env, EXCP_HW_EXCP);
         }
     }
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 62747b02f3..411c7b6e49 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1809,7 +1809,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
-                 env->msr, env->sregs[SR_ESR], env->ear,
+                 env->msr, env->esr, env->ear,
                  env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
                  env->sregs[SR_BTR]);
     qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
@@ -1875,8 +1875,10 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr), "rmsr");
     cpu_SR[SR_EAR] =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
+    cpu_SR[SR_ESR] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr), "resr");
 
-    for (i = SR_EAR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
+    for (i = SR_ESR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
         cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
-- 
2.25.1



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

* [PATCH v2 09/76] target/microblaze: Split out FSR from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (7 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 08/76] target/microblaze: Split out ESR " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 20:51   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 10/76] target/microblaze: Split out BTR " Richard Henderson
                   ` (67 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Continue eliminating the sregs array in favor of individual members.
Does not correct the width of FSR, yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h          | 1 +
 linux-user/microblaze/cpu_loop.c | 4 ++--
 target/microblaze/gdbstub.c      | 4 ++--
 target/microblaze/op_helper.c    | 8 ++++----
 target/microblaze/translate.c    | 6 ++++--
 5 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 7d94af43ed..bcafef99b0 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -240,6 +240,7 @@ struct CPUMBState {
     uint64_t msr;
     uint64_t ear;
     uint64_t esr;
+    uint64_t fsr;
     uint64_t sregs[14];
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index c10e3e0261..da5e98b784 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -96,10 +96,10 @@ void cpu_loop(CPUMBState *env)
                 case ESR_EC_FPU:
                     info.si_signo = TARGET_SIGFPE;
                     info.si_errno = 0;
-                    if (env->sregs[SR_FSR] & FSR_IO) {
+                    if (env->fsr & FSR_IO) {
                         info.si_code = TARGET_FPE_FLTINV;
                     }
-                    if (env->sregs[SR_FSR] & FSR_DZ) {
+                    if (env->fsr & FSR_DZ) {
                         info.si_code = TARGET_FPE_FLTDIV;
                     }
                     info._sifields._sigfault._addr = 0;
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 05e22f233d..2634ce49fc 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -71,7 +71,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->esr;
         break;
     case GDB_FSR:
-        val = env->sregs[SR_FSR];
+        val = env->fsr;
         break;
     case GDB_BTR:
         val = env->sregs[SR_BTR];
@@ -127,7 +127,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->esr = tmp;
         break;
     case GDB_FSR:
-        env->sregs[SR_FSR] = tmp;
+        env->fsr = tmp;
         break;
     case GDB_BTR:
         env->sregs[SR_BTR] = tmp;
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index f01cf9be64..ae57d45536 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -175,19 +175,19 @@ static void update_fpu_flags(CPUMBState *env, int flags)
     int raise = 0;
 
     if (flags & float_flag_invalid) {
-        env->sregs[SR_FSR] |= FSR_IO;
+        env->fsr |= FSR_IO;
         raise = 1;
     }
     if (flags & float_flag_divbyzero) {
-        env->sregs[SR_FSR] |= FSR_DZ;
+        env->fsr |= FSR_DZ;
         raise = 1;
     }
     if (flags & float_flag_overflow) {
-        env->sregs[SR_FSR] |= FSR_OF;
+        env->fsr |= FSR_OF;
         raise = 1;
     }
     if (flags & float_flag_underflow) {
-        env->sregs[SR_FSR] |= FSR_UF;
+        env->fsr |= FSR_UF;
         raise = 1;
     }
     if (raise
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 411c7b6e49..c58c49ea8f 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1810,7 +1810,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
                  env->msr, env->esr, env->ear,
-                 env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
+                 env->debug, env->imm, env->iflags, env->fsr,
                  env->sregs[SR_BTR]);
     qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
                  "eip=%d ie=%d\n",
@@ -1877,8 +1877,10 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_SR[SR_ESR] =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr), "resr");
+    cpu_SR[SR_FSR] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr), "rfsr");
 
-    for (i = SR_ESR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
+    for (i = SR_FSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
         cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
-- 
2.25.1



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

* [PATCH v2 10/76] target/microblaze: Split out BTR from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (8 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 09/76] target/microblaze: Split out FSR " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 20:53   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 11/76] target/microblaze: Split out EDR " Richard Henderson
                   ` (66 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Continue eliminating the sregs array in favor of individual members.
Does not correct the width of BTR, yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       | 1 +
 target/microblaze/gdbstub.c   | 4 ++--
 target/microblaze/helper.c    | 4 ++--
 target/microblaze/translate.c | 6 ++++--
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index bcafef99b0..deddb47abb 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -241,6 +241,7 @@ struct CPUMBState {
     uint64_t ear;
     uint64_t esr;
     uint64_t fsr;
+    uint64_t btr;
     uint64_t sregs[14];
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 2634ce49fc..cde8c169bf 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -74,7 +74,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->fsr;
         break;
     case GDB_BTR:
-        val = env->sregs[SR_BTR];
+        val = env->btr;
         break;
     case GDB_PVR0 ... GDB_PVR11:
         /* PVR12 is intentionally skipped */
@@ -130,7 +130,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->fsr = tmp;
         break;
     case GDB_BTR:
-        env->sregs[SR_BTR] = tmp;
+        env->btr = tmp;
         break;
     case GDB_PVR0 ... GDB_PVR11:
         /* PVR12 is intentionally skipped */
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index ea290be780..b240dc76f6 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -132,7 +132,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             /* Exception breaks branch + dslot sequence?  */
             if (env->iflags & D_FLAG) {
                 env->esr |= 1 << 12 ;
-                env->sregs[SR_BTR] = env->btarget;
+                env->btr = env->btarget;
             }
 
             /* Disable the MMU.  */
@@ -160,7 +160,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             if (env->iflags & D_FLAG) {
                 D(qemu_log("D_FLAG set at exception bimm=%d\n", env->bimm));
                 env->esr |= 1 << 12 ;
-                env->sregs[SR_BTR] = env->btarget;
+                env->btr = env->btarget;
 
                 /* Reexecute the branch.  */
                 env->regs[17] -= 4;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index c58c49ea8f..469e1f103a 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1811,7 +1811,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
                  "rbtr=%" PRIx64 "\n",
                  env->msr, env->esr, env->ear,
                  env->debug, env->imm, env->iflags, env->fsr,
-                 env->sregs[SR_BTR]);
+                 env->btr);
     qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
                  "eip=%d ie=%d\n",
                  env->btaken, env->btarget,
@@ -1879,8 +1879,10 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr), "resr");
     cpu_SR[SR_FSR] =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr), "rfsr");
+    cpu_SR[SR_BTR] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, btr), "rbtr");
 
-    for (i = SR_FSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
+    for (i = SR_BTR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
         cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
                           offsetof(CPUMBState, sregs[i]),
                           special_regnames[i]);
-- 
2.25.1



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

* [PATCH v2 11/76] target/microblaze: Split out EDR from env->sregs
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (9 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 10/76] target/microblaze: Split out BTR " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 12/76] target/microblaze: Split the cpu_SR array Richard Henderson
                   ` (65 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Finish eliminating the sregs array in favor of individual members.
Does not correct the width of EDR, yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  2 +-
 linux-user/elfload.c          |  9 ++++++---
 target/microblaze/gdbstub.c   |  4 ++--
 target/microblaze/translate.c | 16 +++-------------
 4 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index deddb47abb..610ddfb719 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -242,7 +242,7 @@ struct CPUMBState {
     uint64_t esr;
     uint64_t fsr;
     uint64_t btr;
-    uint64_t sregs[14];
+    uint64_t edr;
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
     uint32_t slr, shr;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index fe9dfe795d..bbfb665321 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1032,9 +1032,12 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
         (*regs)[pos++] = tswapreg(env->regs[i]);
     }
 
-    for (i = 0; i < 6; i++) {
-        (*regs)[pos++] = tswapreg(env->sregs[i]);
-    }
+    (*regs)[pos++] = tswapreg(env->pc);
+    (*regs)[pos++] = tswapreg(env->msr);
+    (*regs)[pos++] = 0;
+    (*regs)[pos++] = tswapreg(env->ear);
+    (*regs)[pos++] = 0;
+    (*regs)[pos++] = tswapreg(env->esr);
 }
 
 #endif /* TARGET_MICROBLAZE */
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index cde8c169bf..9cba9d2215 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -81,7 +81,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->pvr.regs[n - GDB_PVR0];
         break;
     case GDB_EDR:
-        val = env->sregs[SR_EDR];
+        val = env->edr;
         break;
     case GDB_SLR:
         val = env->slr;
@@ -137,7 +137,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->pvr.regs[n - GDB_PVR0] = tmp;
         break;
     case GDB_EDR:
-        env->sregs[SR_EDR] = tmp;
+        env->edr = tmp;
         break;
     case GDB_SLR:
         env->slr = tmp;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 469e1f103a..7d307e6b48 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -103,12 +103,6 @@ static const char *regnames[] =
     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
 };
 
-static const char *special_regnames[] =
-{
-    "rpc", "rmsr", "sr2", "rear", "sr4", "resr", "sr6", "rfsr",
-    "sr8", "sr9", "sr10", "rbtr", "sr12", "redr"
-};
-
 static inline void t_sync_flags(DisasContext *dc)
 {
     /* Synch the tb dependent flags between translator and runtime.  */
@@ -1828,7 +1822,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 
     /* Registers that aren't modeled are reported as 0 */
     qemu_fprintf(f, "redr=%" PRIx64 " rpid=0 rzpr=0 rtlbx=0 rtlbsx=0 "
-                    "rtlblo=0 rtlbhi=0\n", env->sregs[SR_EDR]);
+                    "rtlblo=0 rtlbhi=0\n", env->edr);
     qemu_fprintf(f, "slr=%x shr=%x\n", env->slr, env->shr);
     for (i = 0; i < 32; i++) {
         qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
@@ -1881,12 +1875,8 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr), "rfsr");
     cpu_SR[SR_BTR] =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, btr), "rbtr");
-
-    for (i = SR_BTR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
-        cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
-                          offsetof(CPUMBState, sregs[i]),
-                          special_regnames[i]);
-    }
+    cpu_SR[SR_EDR] =
+        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, edr), "redr");
 }
 
 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
-- 
2.25.1



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

* [PATCH v2 12/76] target/microblaze: Split the cpu_SR array
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (10 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 11/76] target/microblaze: Split out EDR " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 13/76] target/microblaze: Fix width of PC and BTARGET Richard Henderson
                   ` (64 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Similar to splitting the sregs array, this will allow further
fixes and cleanups.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/translate.c | 106 +++++++++++++++++++++-------------
 1 file changed, 65 insertions(+), 41 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 7d307e6b48..19d7b8abfd 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -55,7 +55,13 @@
 
 static TCGv_i32 env_debug;
 static TCGv_i32 cpu_R[32];
-static TCGv_i64 cpu_SR[14];
+static TCGv_i64 cpu_pc;
+static TCGv_i64 cpu_msr;
+static TCGv_i64 cpu_ear;
+static TCGv_i64 cpu_esr;
+static TCGv_i64 cpu_fsr;
+static TCGv_i64 cpu_btr;
+static TCGv_i64 cpu_edr;
 static TCGv_i32 env_imm;
 static TCGv_i32 env_btaken;
 static TCGv_i64 env_btarget;
@@ -117,7 +123,7 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
     TCGv_i32 tmp = tcg_const_i32(index);
 
     t_sync_flags(dc);
-    tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
+    tcg_gen_movi_i64(cpu_pc, dc->pc);
     gen_helper_raise_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
     dc->is_jmp = DISAS_UPDATE;
@@ -136,17 +142,17 @@ 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_i64(cpu_SR[SR_PC], dest);
+        tcg_gen_movi_i64(cpu_pc, dest);
         tcg_gen_exit_tb(dc->tb, n);
     } else {
-        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);
+        tcg_gen_movi_i64(cpu_pc, dest);
         tcg_gen_exit_tb(NULL, 0);
     }
 }
 
 static void read_carry(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_extrl_i64_i32(d, cpu_SR[SR_MSR]);
+    tcg_gen_extrl_i64_i32(d, cpu_msr);
     tcg_gen_shri_i32(d, d, 31);
 }
 
@@ -159,8 +165,8 @@ static void write_carry(DisasContext *dc, TCGv_i32 v)
     TCGv_i64 t0 = tcg_temp_new_i64();
     tcg_gen_extu_i32_i64(t0, v);
     /* Deposit bit 0 into MSR_C and the alias MSR_CC.  */
-    tcg_gen_deposit_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0, 2, 1);
-    tcg_gen_deposit_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0, 31, 1);
+    tcg_gen_deposit_i64(cpu_msr, cpu_msr, t0, 2, 1);
+    tcg_gen_deposit_i64(cpu_msr, cpu_msr, t0, 31, 1);
     tcg_temp_free_i64(t0);
 }
 
@@ -180,7 +186,7 @@ static bool trap_illegal(DisasContext *dc, bool cond)
 {
     if (cond && (dc->tb_flags & MSR_EE_FLAG)
         && dc->cpu->cfg.illegal_opcode_exception) {
-        tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i64(cpu_esr, ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return cond;
@@ -196,7 +202,7 @@ static bool trap_userspace(DisasContext *dc, bool cond)
     bool cond_user = cond && mem_index == MMU_USER_IDX;
 
     if (cond_user && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
+        tcg_gen_movi_i64(cpu_esr, ESR_EC_PRIVINSN);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return cond_user;
@@ -431,7 +437,7 @@ static void dec_xor(DisasContext *dc)
 
 static inline void msr_read(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_extrl_i64_i32(d, cpu_SR[SR_MSR]);
+    tcg_gen_extrl_i64_i32(d, cpu_msr);
 }
 
 static inline void msr_write(DisasContext *dc, TCGv_i32 v)
@@ -443,8 +449,8 @@ static inline void msr_write(DisasContext *dc, TCGv_i32 v)
     /* PVR bit is not writable.  */
     tcg_gen_extu_i32_i64(t, v);
     tcg_gen_andi_i64(t, t, ~MSR_PVR);
-    tcg_gen_andi_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
-    tcg_gen_or_i64(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t);
+    tcg_gen_andi_i64(cpu_msr, cpu_msr, MSR_PVR);
+    tcg_gen_or_i64(cpu_msr, cpu_msr, t);
     tcg_temp_free_i64(t);
 }
 
@@ -503,7 +509,7 @@ static void dec_msr(DisasContext *dc)
         msr_write(dc, t0);
         tcg_temp_free_i32(t0);
         tcg_temp_free_i32(t1);
-        tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc + 4);
+        tcg_gen_movi_i64(cpu_pc, dc->pc + 4);
         dc->is_jmp = DISAS_UPDATE;
         return;
     }
@@ -535,15 +541,25 @@ static void dec_msr(DisasContext *dc)
     if (to) {
         LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
         switch (sr) {
-            case 0:
+            case SR_PC:
                 break;
-            case 1:
+            case SR_MSR:
                 msr_write(dc, cpu_R[dc->ra]);
                 break;
             case SR_EAR:
+                tcg_gen_extu_i32_i64(cpu_ear, cpu_R[dc->ra]);
+                break;
             case SR_ESR:
+                tcg_gen_extu_i32_i64(cpu_esr, cpu_R[dc->ra]);
+                break;
             case SR_FSR:
-                tcg_gen_extu_i32_i64(cpu_SR[sr], cpu_R[dc->ra]);
+                tcg_gen_extu_i32_i64(cpu_fsr, cpu_R[dc->ra]);
+                break;
+            case SR_BTR:
+                tcg_gen_extu_i32_i64(cpu_btr, cpu_R[dc->ra]);
+                break;
+            case SR_EDR:
+                tcg_gen_extu_i32_i64(cpu_edr, cpu_R[dc->ra]);
                 break;
             case 0x800:
                 tcg_gen_st_i32(cpu_R[dc->ra],
@@ -561,22 +577,30 @@ static void dec_msr(DisasContext *dc)
         LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm);
 
         switch (sr) {
-            case 0:
+            case SR_PC:
                 tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
                 break;
-            case 1:
+            case SR_MSR:
                 msr_read(dc, cpu_R[dc->rd]);
                 break;
             case SR_EAR:
                 if (extended) {
-                    tcg_gen_extrh_i64_i32(cpu_R[dc->rd], cpu_SR[sr]);
-                    break;
+                    tcg_gen_extrh_i64_i32(cpu_R[dc->rd], cpu_ear);
+                } else {
+                    tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_ear);
                 }
+                break;
             case SR_ESR:
+                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_esr);
+                break;
             case SR_FSR:
+                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_fsr);
+                break;
             case SR_BTR:
+                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_btr);
+                break;
             case SR_EDR:
-                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_SR[sr]);
+                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_edr);
                 break;
             case 0x800:
                 tcg_gen_ld_i32(cpu_R[dc->rd],
@@ -749,7 +773,7 @@ static void dec_bit(DisasContext *dc)
             t0 = tcg_temp_new_i32();
 
             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
-            tcg_gen_extrl_i64_i32(t0, cpu_SR[SR_MSR]);
+            tcg_gen_extrl_i64_i32(t0, cpu_msr);
             tcg_gen_andi_i32(t0, t0, MSR_CC);
             write_carry(dc, cpu_R[dc->ra]);
             if (dc->rd) {
@@ -995,7 +1019,7 @@ static void dec_load(DisasContext *dc)
         TCGv_i32 treg = tcg_const_i32(dc->rd);
         TCGv_i32 tsize = tcg_const_i32(size - 1);
 
-        tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
+        tcg_gen_movi_i64(cpu_pc, dc->pc);
         gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
 
         tcg_temp_free_i32(t0);
@@ -1115,7 +1139,7 @@ static void dec_store(DisasContext *dc)
         TCGv_i32 treg = tcg_const_i32(dc->rd);
         TCGv_i32 tsize = tcg_const_i32(size - 1);
 
-        tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
+        tcg_gen_movi_i64(cpu_pc, dc->pc);
         /* FIXME: if the alignment is wrong, we should restore the value
          *        in memory. One possible way to achieve this is to probe
          *        the MMU prior to the memaccess, thay way we could put
@@ -1169,7 +1193,7 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i64 pc_true, TCGv_i64 pc_false)
     TCGv_i64 tmp_zero = tcg_const_i64(0);
 
     tcg_gen_extu_i32_i64(tmp_btaken, env_btaken);
-    tcg_gen_movcond_i64(TCG_COND_NE, cpu_SR[SR_PC],
+    tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc,
                         tmp_btaken, tmp_zero,
                         pc_true, pc_false);
 
@@ -1253,7 +1277,7 @@ static void dec_br(DisasContext *dc)
             tcg_gen_st_i32(tmp_1, cpu_env,
                            -offsetof(MicroBlazeCPU, env)
                            +offsetof(CPUState, halted));
-            tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc + 4);
+            tcg_gen_movi_i64(cpu_pc, dc->pc + 4);
             gen_helper_raise_exception(cpu_env, tmp_hlt);
             tcg_temp_free_i32(tmp_hlt);
             tcg_temp_free_i32(tmp_1);
@@ -1309,7 +1333,7 @@ static inline void do_rti(DisasContext *dc)
     TCGv_i32 t0, t1;
     t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new_i32();
-    tcg_gen_extrl_i64_i32(t1, cpu_SR[SR_MSR]);
+    tcg_gen_extrl_i64_i32(t1, cpu_msr);
     tcg_gen_shri_i32(t0, t1, 1);
     tcg_gen_ori_i32(t1, t1, MSR_IE);
     tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
@@ -1327,7 +1351,7 @@ static inline void do_rtb(DisasContext *dc)
     TCGv_i32 t0, t1;
     t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new_i32();
-    tcg_gen_extrl_i64_i32(t1, cpu_SR[SR_MSR]);
+    tcg_gen_extrl_i64_i32(t1, cpu_msr);
     tcg_gen_andi_i32(t1, t1, ~MSR_BIP);
     tcg_gen_shri_i32(t0, t1, 1);
     tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
@@ -1346,7 +1370,7 @@ static inline void do_rte(DisasContext *dc)
     t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new_i32();
 
-    tcg_gen_extrl_i64_i32(t1, cpu_SR[SR_MSR]);
+    tcg_gen_extrl_i64_i32(t1, cpu_msr);
     tcg_gen_ori_i32(t1, t1, MSR_EE);
     tcg_gen_andi_i32(t1, t1, ~MSR_EIP);
     tcg_gen_shri_i32(t0, t1, 1);
@@ -1401,7 +1425,7 @@ static void dec_rts(DisasContext *dc)
 static int dec_check_fpuv2(DisasContext *dc)
 {
     if ((dc->cpu->cfg.use_fpu != 2) && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_i64(cpu_SR[SR_ESR], ESR_EC_FPU);
+        tcg_gen_movi_i64(cpu_esr, ESR_EC_FPU);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return (dc->cpu->cfg.use_fpu == 2) ? PVR2_USE_FPU2_MASK : 0;
@@ -1652,7 +1676,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
 
 #if SIM_COMPAT
         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-            tcg_gen_movi_i64(cpu_SR[SR_PC], dc->pc);
+            tcg_gen_movi_i64(cpu_pc, dc->pc);
             gen_helper_debug();
         }
 #endif
@@ -1730,7 +1754,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
         if (dc->tb_flags & D_FLAG) {
             dc->is_jmp = DISAS_UPDATE;
-            tcg_gen_movi_i64(cpu_SR[SR_PC], npc);
+            tcg_gen_movi_i64(cpu_pc, npc);
             sync_jmpstate(dc);
         } else
             npc = dc->jmp_pc;
@@ -1740,7 +1764,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     if (dc->is_jmp == DISAS_NEXT
         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
         dc->is_jmp = DISAS_UPDATE;
-        tcg_gen_movi_i64(cpu_SR[SR_PC], npc);
+        tcg_gen_movi_i64(cpu_pc, npc);
     }
     t_sync_flags(dc);
 
@@ -1748,7 +1772,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
-            tcg_gen_movi_i64(cpu_SR[SR_PC], npc);
+            tcg_gen_movi_i64(cpu_pc, npc);
         }
         gen_helper_raise_exception(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
@@ -1863,19 +1887,19 @@ void mb_tcg_init(void)
                           regnames[i]);
     }
 
-    cpu_SR[SR_PC] =
+    cpu_pc =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, pc), "rpc");
-    cpu_SR[SR_MSR] =
+    cpu_msr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr), "rmsr");
-    cpu_SR[SR_EAR] =
+    cpu_ear =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
-    cpu_SR[SR_ESR] =
+    cpu_esr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr), "resr");
-    cpu_SR[SR_FSR] =
+    cpu_fsr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr), "rfsr");
-    cpu_SR[SR_BTR] =
+    cpu_btr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, btr), "rbtr");
-    cpu_SR[SR_EDR] =
+    cpu_edr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, edr), "redr");
 }
 
-- 
2.25.1



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

* [PATCH v2 13/76] target/microblaze: Fix width of PC and BTARGET
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (11 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 12/76] target/microblaze: Split the cpu_SR array Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 14/76] target/microblaze: Fix width of MSR Richard Henderson
                   ` (63 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The program counter is only 32-bits wide.  Do not use a 64-bit
type to represent it.  Since they are so closely related, fix
btarget at the same time.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  4 +-
 target/microblaze/helper.c    | 16 +++----
 target/microblaze/mmu.c       |  4 +-
 target/microblaze/op_helper.c |  4 +-
 target/microblaze/translate.c | 78 ++++++++++++++---------------------
 5 files changed, 43 insertions(+), 63 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 610ddfb719..f4c3c09b09 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -231,12 +231,12 @@ typedef struct CPUMBState CPUMBState;
 struct CPUMBState {
     uint32_t debug;
     uint32_t btaken;
-    uint64_t btarget;
+    uint32_t btarget;
     uint32_t bimm;
 
     uint32_t imm;
     uint32_t regs[32];
-    uint64_t pc;
+    uint32_t pc;
     uint64_t msr;
     uint64_t ear;
     uint64_t esr;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index b240dc76f6..b95617a81a 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -143,7 +143,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             env->msr |= MSR_EIP;
 
             qemu_log_mask(CPU_LOG_INT,
-                          "hw exception at pc=%" PRIx64 " ear=%" PRIx64 " "
+                          "hw exception at pc=%x ear=%" PRIx64 " "
                           "esr=%" PRIx64 " iflags=%x\n",
                           env->pc, env->ear,
                           env->esr, env->iflags);
@@ -167,8 +167,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                 /* was the branch immprefixed?.  */
                 if (env->bimm) {
                     qemu_log_mask(CPU_LOG_INT,
-                                  "bimm exception at pc=%" PRIx64 " "
-                                  "iflags=%x\n",
+                                  "bimm exception at pc=%x iflags=%x\n",
                                   env->pc, env->iflags);
                     env->regs[17] -= 4;
                     log_cpu_state_mask(CPU_LOG_INT, cs, 0);
@@ -186,8 +185,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             env->msr |= MSR_EIP;
 
             qemu_log_mask(CPU_LOG_INT,
-                          "exception at pc=%" PRIx64 " ear=%" PRIx64 " "
-                          "iflags=%x\n",
+                          "exception at pc=%x ear=%" PRIx64 " iflags=%x\n",
                           env->pc, env->ear, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
@@ -224,8 +222,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 #endif
             qemu_log_mask(CPU_LOG_INT,
-                         "interrupt at pc=%" PRIx64 " msr=%" PRIx64 " %x "
-                         "iflags=%x\n",
+                         "interrupt at pc=%x msr=%" PRIx64 " %x iflags=%x\n",
                          env->pc, env->msr, t, env->iflags);
 
             env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE);
@@ -242,9 +239,8 @@ void mb_cpu_do_interrupt(CPUState *cs)
             assert(!(env->iflags & D_FLAG));
             t = (env->msr & (MSR_VM | MSR_UM)) << 1;
             qemu_log_mask(CPU_LOG_INT,
-                        "break at pc=%" PRIx64 " msr=%" PRIx64 " %x "
-                        "iflags=%x\n",
-                        env->pc, env->msr, t, env->iflags);
+                          "break at pc=%x msr=%" PRIx64 " %x iflags=%x\n",
+                          env->pc, env->msr, t, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             env->msr |= t;
diff --git a/target/microblaze/mmu.c b/target/microblaze/mmu.c
index 3f403b567b..6e583d78d9 100644
--- a/target/microblaze/mmu.c
+++ b/target/microblaze/mmu.c
@@ -250,8 +250,8 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
             if (rn == MMU_R_TLBHI) {
                 if (i < 3 && !(v & TLB_VALID) && qemu_loglevel_mask(~0))
                     qemu_log_mask(LOG_GUEST_ERROR,
-                             "invalidating index %x at pc=%" PRIx64 "\n",
-                             i, env->pc);
+                                  "invalidating index %x at pc=%x\n",
+                                  i, env->pc);
                 env->mmu.tids[i] = env->mmu.regs[MMU_R_PID] & 0xff;
                 mmu_flush_idx(env, i);
             }
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index ae57d45536..fdf706a723 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -75,12 +75,12 @@ void helper_debug(CPUMBState *env)
 {
     int i;
 
-    qemu_log("PC=%" PRIx64 "\n", env->pc);
+    qemu_log("PC=%08x\n", env->pc);
     qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
              env->msr, env->esr, env->ear,
              env->debug, env->imm, env->iflags);
-    qemu_log("btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) eip=%d ie=%d\n",
+    qemu_log("btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
              env->btaken, env->btarget,
              (env->msr & MSR_UM) ? "user" : "kernel",
              (env->msr & MSR_UMS) ? "user" : "kernel",
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 19d7b8abfd..72783c1d8a 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -55,7 +55,7 @@
 
 static TCGv_i32 env_debug;
 static TCGv_i32 cpu_R[32];
-static TCGv_i64 cpu_pc;
+static TCGv_i32 cpu_pc;
 static TCGv_i64 cpu_msr;
 static TCGv_i64 cpu_ear;
 static TCGv_i64 cpu_esr;
@@ -64,7 +64,7 @@ static TCGv_i64 cpu_btr;
 static TCGv_i64 cpu_edr;
 static TCGv_i32 env_imm;
 static TCGv_i32 env_btaken;
-static TCGv_i64 env_btarget;
+static TCGv_i32 cpu_btarget;
 static TCGv_i32 env_iflags;
 static TCGv env_res_addr;
 static TCGv_i32 env_res_val;
@@ -123,7 +123,7 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
     TCGv_i32 tmp = tcg_const_i32(index);
 
     t_sync_flags(dc);
-    tcg_gen_movi_i64(cpu_pc, dc->pc);
+    tcg_gen_movi_i32(cpu_pc, dc->pc);
     gen_helper_raise_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
     dc->is_jmp = DISAS_UPDATE;
@@ -142,10 +142,10 @@ 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_i64(cpu_pc, dest);
+        tcg_gen_movi_i32(cpu_pc, dest);
         tcg_gen_exit_tb(dc->tb, n);
     } else {
-        tcg_gen_movi_i64(cpu_pc, dest);
+        tcg_gen_movi_i32(cpu_pc, dest);
         tcg_gen_exit_tb(NULL, 0);
     }
 }
@@ -509,7 +509,7 @@ static void dec_msr(DisasContext *dc)
         msr_write(dc, t0);
         tcg_temp_free_i32(t0);
         tcg_temp_free_i32(t1);
-        tcg_gen_movi_i64(cpu_pc, dc->pc + 4);
+        tcg_gen_movi_i32(cpu_pc, dc->pc + 4);
         dc->is_jmp = DISAS_UPDATE;
         return;
     }
@@ -850,7 +850,7 @@ static inline void sync_jmpstate(DisasContext *dc)
             tcg_gen_movi_i32(env_btaken, 1);
         }
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_movi_i64(env_btarget, dc->jmp_pc);
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
     }
 }
 
@@ -1019,7 +1019,7 @@ static void dec_load(DisasContext *dc)
         TCGv_i32 treg = tcg_const_i32(dc->rd);
         TCGv_i32 tsize = tcg_const_i32(size - 1);
 
-        tcg_gen_movi_i64(cpu_pc, dc->pc);
+        tcg_gen_movi_i32(cpu_pc, dc->pc);
         gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
 
         tcg_temp_free_i32(t0);
@@ -1139,7 +1139,7 @@ static void dec_store(DisasContext *dc)
         TCGv_i32 treg = tcg_const_i32(dc->rd);
         TCGv_i32 tsize = tcg_const_i32(size - 1);
 
-        tcg_gen_movi_i64(cpu_pc, dc->pc);
+        tcg_gen_movi_i32(cpu_pc, dc->pc);
         /* FIXME: if the alignment is wrong, we should restore the value
          *        in memory. One possible way to achieve this is to probe
          *        the MMU prior to the memaccess, thay way we could put
@@ -1187,18 +1187,15 @@ static inline void eval_cc(DisasContext *dc, unsigned int cc,
     }
 }
 
-static void eval_cond_jmp(DisasContext *dc, TCGv_i64 pc_true, TCGv_i64 pc_false)
+static void eval_cond_jmp(DisasContext *dc, TCGv_i32 pc_true, TCGv_i32 pc_false)
 {
-    TCGv_i64 tmp_btaken = tcg_temp_new_i64();
-    TCGv_i64 tmp_zero = tcg_const_i64(0);
+    TCGv_i32 zero = tcg_const_i32(0);
 
-    tcg_gen_extu_i32_i64(tmp_btaken, env_btaken);
-    tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc,
-                        tmp_btaken, tmp_zero,
+    tcg_gen_movcond_i32(TCG_COND_NE, cpu_pc,
+                        env_btaken, zero,
                         pc_true, pc_false);
 
-    tcg_temp_free_i64(tmp_btaken);
-    tcg_temp_free_i64(tmp_zero);
+    tcg_temp_free_i32(zero);
 }
 
 static void dec_setup_dslot(DisasContext *dc)
@@ -1229,14 +1226,12 @@ static void dec_bcc(DisasContext *dc)
     if (dec_alu_op_b_is_small_imm(dc)) {
         int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
 
-        tcg_gen_movi_i64(env_btarget, dc->pc + offset);
+        tcg_gen_movi_i32(cpu_btarget, dc->pc + offset);
         dc->jmp = JMP_DIRECT_CC;
         dc->jmp_pc = dc->pc + offset;
     } else {
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
-        tcg_gen_addi_i64(env_btarget, env_btarget, dc->pc);
-        tcg_gen_andi_i64(env_btarget, env_btarget, UINT32_MAX);
+        tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
     }
     eval_cc(dc, cc, env_btaken, cpu_R[dc->ra]);
 }
@@ -1277,7 +1272,7 @@ static void dec_br(DisasContext *dc)
             tcg_gen_st_i32(tmp_1, cpu_env,
                            -offsetof(MicroBlazeCPU, env)
                            +offsetof(CPUState, halted));
-            tcg_gen_movi_i64(cpu_pc, dc->pc + 4);
+            tcg_gen_movi_i32(cpu_pc, dc->pc + 4);
             gen_helper_raise_exception(cpu_env, tmp_hlt);
             tcg_temp_free_i32(tmp_hlt);
             tcg_temp_free_i32(tmp_1);
@@ -1303,7 +1298,7 @@ static void dec_br(DisasContext *dc)
     dc->jmp = JMP_INDIRECT;
     if (abs) {
         tcg_gen_movi_i32(env_btaken, 1);
-        tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
+        tcg_gen_mov_i32(cpu_btarget, *(dec_alu_op_b(dc)));
         if (link && !dslot) {
             if (!(dc->tb_flags & IMM_FLAG) && (dc->imm == 8 || dc->imm == 0x18))
                 t_gen_raise_exception(dc, EXCP_BREAK);
@@ -1321,9 +1316,7 @@ static void dec_br(DisasContext *dc)
             dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
         } else {
             tcg_gen_movi_i32(env_btaken, 1);
-            tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
-            tcg_gen_addi_i64(env_btarget, env_btarget, dc->pc);
-            tcg_gen_andi_i64(env_btarget, env_btarget, UINT32_MAX);
+            tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
         }
     }
 }
@@ -1387,7 +1380,6 @@ static inline void do_rte(DisasContext *dc)
 static void dec_rts(DisasContext *dc)
 {
     unsigned int b_bit, i_bit, e_bit;
-    TCGv_i64 tmp64;
 
     i_bit = dc->ir & (1 << 21);
     b_bit = dc->ir & (1 << 22);
@@ -1413,13 +1405,7 @@ static void dec_rts(DisasContext *dc)
 
     dc->jmp = JMP_INDIRECT;
     tcg_gen_movi_i32(env_btaken, 1);
-
-    tmp64 = tcg_temp_new_i64();
-    tcg_gen_extu_i32_i64(env_btarget, *(dec_alu_op_b(dc)));
-    tcg_gen_extu_i32_i64(tmp64, cpu_R[dc->ra]);
-    tcg_gen_add_i64(env_btarget, env_btarget, tmp64);
-    tcg_gen_andi_i64(env_btarget, env_btarget, UINT32_MAX);
-    tcg_temp_free_i64(tmp64);
+    tcg_gen_add_i32(cpu_btarget, cpu_R[dc->ra], *dec_alu_op_b(dc));
 }
 
 static int dec_check_fpuv2(DisasContext *dc)
@@ -1676,7 +1662,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
 
 #if SIM_COMPAT
         if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-            tcg_gen_movi_i64(cpu_pc, dc->pc);
+            tcg_gen_movi_i32(cpu_pc, dc->pc);
             gen_helper_debug();
         }
 #endif
@@ -1718,10 +1704,9 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                 dc->tb_flags &= ~D_FLAG;
                 /* If it is a direct jump, try direct chaining.  */
                 if (dc->jmp == JMP_INDIRECT) {
-                    TCGv_i64 tmp_pc = tcg_const_i64(dc->pc);
-                    eval_cond_jmp(dc, env_btarget, tmp_pc);
-                    tcg_temp_free_i64(tmp_pc);
-
+                    TCGv_i32 tmp_pc = tcg_const_i32(dc->pc);
+                    eval_cond_jmp(dc, cpu_btarget, tmp_pc);
+                    tcg_temp_free_i32(tmp_pc);
                     dc->is_jmp = DISAS_JUMP;
                 } else if (dc->jmp == JMP_DIRECT) {
                     t_sync_flags(dc);
@@ -1754,7 +1739,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
         if (dc->tb_flags & D_FLAG) {
             dc->is_jmp = DISAS_UPDATE;
-            tcg_gen_movi_i64(cpu_pc, npc);
+            tcg_gen_movi_i32(cpu_pc, npc);
             sync_jmpstate(dc);
         } else
             npc = dc->jmp_pc;
@@ -1764,7 +1749,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     if (dc->is_jmp == DISAS_NEXT
         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
         dc->is_jmp = DISAS_UPDATE;
-        tcg_gen_movi_i64(cpu_pc, npc);
+        tcg_gen_movi_i32(cpu_pc, npc);
     }
     t_sync_flags(dc);
 
@@ -1772,7 +1757,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
-            tcg_gen_movi_i64(cpu_pc, npc);
+            tcg_gen_movi_i32(cpu_pc, npc);
         }
         gen_helper_raise_exception(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
@@ -1822,7 +1807,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
         return;
     }
 
-    qemu_fprintf(f, "IN: PC=%" PRIx64 " %s\n",
+    qemu_fprintf(f, "IN: PC=%x %s\n",
                  env->pc, lookup_symbol(env->pc));
     qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
@@ -1830,8 +1815,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
                  env->msr, env->esr, env->ear,
                  env->debug, env->imm, env->iflags, env->fsr,
                  env->btr);
-    qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
-                 "eip=%d ie=%d\n",
+    qemu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
                  env->btaken, env->btarget,
                  (env->msr & MSR_UM) ? "user" : "kernel",
                  (env->msr & MSR_UMS) ? "user" : "kernel",
@@ -1869,7 +1853,7 @@ void mb_tcg_init(void)
     env_imm = tcg_global_mem_new_i32(cpu_env,
                     offsetof(CPUMBState, imm),
                     "imm");
-    env_btarget = tcg_global_mem_new_i64(cpu_env,
+    cpu_btarget = tcg_global_mem_new_i32(cpu_env,
                      offsetof(CPUMBState, btarget),
                      "btarget");
     env_btaken = tcg_global_mem_new_i32(cpu_env,
@@ -1888,7 +1872,7 @@ void mb_tcg_init(void)
     }
 
     cpu_pc =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, pc), "rpc");
+        tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, pc), "rpc");
     cpu_msr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr), "rmsr");
     cpu_ear =
-- 
2.25.1



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

* [PATCH v2 14/76] target/microblaze: Fix width of MSR
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (12 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 13/76] target/microblaze: Fix width of PC and BTARGET Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 15/76] target/microblaze: Fix width of ESR Richard Henderson
                   ` (62 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The machine status register is only 32-bits wide.
Do not use a 64-bit type to represent it.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  2 +-
 target/microblaze/helper.c    |  4 ++--
 target/microblaze/op_helper.c |  2 +-
 target/microblaze/translate.c | 38 ++++++++++++-----------------------
 4 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index f4c3c09b09..019e5dfa26 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -237,7 +237,7 @@ struct CPUMBState {
     uint32_t imm;
     uint32_t regs[32];
     uint32_t pc;
-    uint64_t msr;
+    uint32_t msr;
     uint64_t ear;
     uint64_t esr;
     uint64_t fsr;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index b95617a81a..af79091fd2 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -222,7 +222,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 #endif
             qemu_log_mask(CPU_LOG_INT,
-                         "interrupt at pc=%x msr=%" PRIx64 " %x iflags=%x\n",
+                         "interrupt at pc=%x msr=%x %x iflags=%x\n",
                          env->pc, env->msr, t, env->iflags);
 
             env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE);
@@ -239,7 +239,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             assert(!(env->iflags & D_FLAG));
             t = (env->msr & (MSR_VM | MSR_UM)) << 1;
             qemu_log_mask(CPU_LOG_INT,
-                          "break at pc=%x msr=%" PRIx64 " %x iflags=%x\n",
+                          "break at pc=%x msr=%x %x iflags=%x\n",
                           env->pc, env->msr, t, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index fdf706a723..a7f6cb71f1 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -76,7 +76,7 @@ void helper_debug(CPUMBState *env)
     int i;
 
     qemu_log("PC=%08x\n", env->pc);
-    qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
+    qemu_log("rmsr=%x resr=%" PRIx64 " rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
              env->msr, env->esr, env->ear,
              env->debug, env->imm, env->iflags);
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 72783c1d8a..0e71e7ed01 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -56,7 +56,7 @@
 static TCGv_i32 env_debug;
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
-static TCGv_i64 cpu_msr;
+static TCGv_i32 cpu_msr;
 static TCGv_i64 cpu_ear;
 static TCGv_i64 cpu_esr;
 static TCGv_i64 cpu_fsr;
@@ -152,8 +152,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 
 static void read_carry(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_extrl_i64_i32(d, cpu_msr);
-    tcg_gen_shri_i32(d, d, 31);
+    tcg_gen_shri_i32(d, cpu_msr, 31);
 }
 
 /*
@@ -162,12 +161,9 @@ static void read_carry(DisasContext *dc, TCGv_i32 d)
  */
 static void write_carry(DisasContext *dc, TCGv_i32 v)
 {
-    TCGv_i64 t0 = tcg_temp_new_i64();
-    tcg_gen_extu_i32_i64(t0, v);
     /* Deposit bit 0 into MSR_C and the alias MSR_CC.  */
-    tcg_gen_deposit_i64(cpu_msr, cpu_msr, t0, 2, 1);
-    tcg_gen_deposit_i64(cpu_msr, cpu_msr, t0, 31, 1);
-    tcg_temp_free_i64(t0);
+    tcg_gen_deposit_i32(cpu_msr, cpu_msr, v, 2, 1);
+    tcg_gen_deposit_i32(cpu_msr, cpu_msr, v, 31, 1);
 }
 
 static void write_carryi(DisasContext *dc, bool carry)
@@ -437,21 +433,14 @@ static void dec_xor(DisasContext *dc)
 
 static inline void msr_read(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_extrl_i64_i32(d, cpu_msr);
+    tcg_gen_mov_i32(d, cpu_msr);
 }
 
 static inline void msr_write(DisasContext *dc, TCGv_i32 v)
 {
-    TCGv_i64 t;
-
-    t = tcg_temp_new_i64();
     dc->cpustate_changed = 1;
-    /* PVR bit is not writable.  */
-    tcg_gen_extu_i32_i64(t, v);
-    tcg_gen_andi_i64(t, t, ~MSR_PVR);
-    tcg_gen_andi_i64(cpu_msr, cpu_msr, MSR_PVR);
-    tcg_gen_or_i64(cpu_msr, cpu_msr, t);
-    tcg_temp_free_i64(t);
+    /* PVR bit is not writable, and is never set. */
+    tcg_gen_andi_i32(cpu_msr, v, ~MSR_PVR);
 }
 
 static void dec_msr(DisasContext *dc)
@@ -773,8 +762,7 @@ static void dec_bit(DisasContext *dc)
             t0 = tcg_temp_new_i32();
 
             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
-            tcg_gen_extrl_i64_i32(t0, cpu_msr);
-            tcg_gen_andi_i32(t0, t0, MSR_CC);
+            tcg_gen_andi_i32(t0, cpu_msr, MSR_CC);
             write_carry(dc, cpu_R[dc->ra]);
             if (dc->rd) {
                 tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
@@ -1326,7 +1314,7 @@ static inline void do_rti(DisasContext *dc)
     TCGv_i32 t0, t1;
     t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new_i32();
-    tcg_gen_extrl_i64_i32(t1, cpu_msr);
+    tcg_gen_mov_i32(t1, cpu_msr);
     tcg_gen_shri_i32(t0, t1, 1);
     tcg_gen_ori_i32(t1, t1, MSR_IE);
     tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
@@ -1344,7 +1332,7 @@ static inline void do_rtb(DisasContext *dc)
     TCGv_i32 t0, t1;
     t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new_i32();
-    tcg_gen_extrl_i64_i32(t1, cpu_msr);
+    tcg_gen_mov_i32(t1, cpu_msr);
     tcg_gen_andi_i32(t1, t1, ~MSR_BIP);
     tcg_gen_shri_i32(t0, t1, 1);
     tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
@@ -1363,7 +1351,7 @@ static inline void do_rte(DisasContext *dc)
     t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new_i32();
 
-    tcg_gen_extrl_i64_i32(t1, cpu_msr);
+    tcg_gen_mov_i32(t1, cpu_msr);
     tcg_gen_ori_i32(t1, t1, MSR_EE);
     tcg_gen_andi_i32(t1, t1, ~MSR_EIP);
     tcg_gen_shri_i32(t0, t1, 1);
@@ -1809,7 +1797,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 
     qemu_fprintf(f, "IN: PC=%x %s\n",
                  env->pc, lookup_symbol(env->pc));
-    qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
+    qemu_fprintf(f, "rmsr=%x resr=%" PRIx64 " rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
                  env->msr, env->esr, env->ear,
@@ -1874,7 +1862,7 @@ void mb_tcg_init(void)
     cpu_pc =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, pc), "rpc");
     cpu_msr =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr), "rmsr");
+        tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, msr), "rmsr");
     cpu_ear =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_esr =
-- 
2.25.1



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

* [PATCH v2 15/76] target/microblaze: Fix width of ESR
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (13 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 14/76] target/microblaze: Fix width of MSR Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 16/76] target/microblaze: Fix width of FSR Richard Henderson
                   ` (61 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The exception status register is only 32-bits wide.
Do not use a 64-bit type to represent it.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h          |  2 +-
 linux-user/microblaze/cpu_loop.c |  2 +-
 target/microblaze/helper.c       |  2 +-
 target/microblaze/op_helper.c    |  2 +-
 target/microblaze/translate.c    | 16 ++++++++--------
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 019e5dfa26..aaac0c9a6c 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -239,7 +239,7 @@ struct CPUMBState {
     uint32_t pc;
     uint32_t msr;
     uint64_t ear;
-    uint64_t esr;
+    uint32_t esr;
     uint64_t fsr;
     uint64_t btr;
     uint64_t edr;
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index da5e98b784..3de99ea311 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -106,7 +106,7 @@ void cpu_loop(CPUMBState *env)
                     queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                     break;
                 default:
-                    fprintf(stderr, "Unhandled hw-exception: 0x%" PRIx64 "\n",
+                    fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
                             env->esr & ESR_EC_MASK);
                     cpu_dump_state(cs, stderr, 0);
                     exit(EXIT_FAILURE);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index af79091fd2..b2373f6a23 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -144,7 +144,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
 
             qemu_log_mask(CPU_LOG_INT,
                           "hw exception at pc=%x ear=%" PRIx64 " "
-                          "esr=%" PRIx64 " iflags=%x\n",
+                          "esr=%x iflags=%x\n",
                           env->pc, env->ear,
                           env->esr, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index a7f6cb71f1..dc2bec0c99 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -76,7 +76,7 @@ void helper_debug(CPUMBState *env)
     int i;
 
     qemu_log("PC=%08x\n", env->pc);
-    qemu_log("rmsr=%x resr=%" PRIx64 " rear=%" PRIx64 " "
+    qemu_log("rmsr=%x resr=%x rear=%" PRIx64 " "
              "debug[%x] imm=%x iflags=%x\n",
              env->msr, env->esr, env->ear,
              env->debug, env->imm, env->iflags);
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 0e71e7ed01..f63aae6de9 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -58,7 +58,7 @@ static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
 static TCGv_i64 cpu_ear;
-static TCGv_i64 cpu_esr;
+static TCGv_i32 cpu_esr;
 static TCGv_i64 cpu_fsr;
 static TCGv_i64 cpu_btr;
 static TCGv_i64 cpu_edr;
@@ -182,7 +182,7 @@ static bool trap_illegal(DisasContext *dc, bool cond)
 {
     if (cond && (dc->tb_flags & MSR_EE_FLAG)
         && dc->cpu->cfg.illegal_opcode_exception) {
-        tcg_gen_movi_i64(cpu_esr, ESR_EC_ILLEGAL_OP);
+        tcg_gen_movi_i32(cpu_esr, ESR_EC_ILLEGAL_OP);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return cond;
@@ -198,7 +198,7 @@ static bool trap_userspace(DisasContext *dc, bool cond)
     bool cond_user = cond && mem_index == MMU_USER_IDX;
 
     if (cond_user && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_i64(cpu_esr, ESR_EC_PRIVINSN);
+        tcg_gen_movi_i32(cpu_esr, ESR_EC_PRIVINSN);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return cond_user;
@@ -539,7 +539,7 @@ static void dec_msr(DisasContext *dc)
                 tcg_gen_extu_i32_i64(cpu_ear, cpu_R[dc->ra]);
                 break;
             case SR_ESR:
-                tcg_gen_extu_i32_i64(cpu_esr, cpu_R[dc->ra]);
+                tcg_gen_mov_i32(cpu_esr, cpu_R[dc->ra]);
                 break;
             case SR_FSR:
                 tcg_gen_extu_i32_i64(cpu_fsr, cpu_R[dc->ra]);
@@ -580,7 +580,7 @@ static void dec_msr(DisasContext *dc)
                 }
                 break;
             case SR_ESR:
-                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_esr);
+                tcg_gen_mov_i32(cpu_R[dc->rd], cpu_esr);
                 break;
             case SR_FSR:
                 tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_fsr);
@@ -1399,7 +1399,7 @@ static void dec_rts(DisasContext *dc)
 static int dec_check_fpuv2(DisasContext *dc)
 {
     if ((dc->cpu->cfg.use_fpu != 2) && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_i64(cpu_esr, ESR_EC_FPU);
+        tcg_gen_movi_i32(cpu_esr, ESR_EC_FPU);
         t_gen_raise_exception(dc, EXCP_HW_EXCP);
     }
     return (dc->cpu->cfg.use_fpu == 2) ? PVR2_USE_FPU2_MASK : 0;
@@ -1797,7 +1797,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 
     qemu_fprintf(f, "IN: PC=%x %s\n",
                  env->pc, lookup_symbol(env->pc));
-    qemu_fprintf(f, "rmsr=%x resr=%" PRIx64 " rear=%" PRIx64 " "
+    qemu_fprintf(f, "rmsr=%x resr=%x rear=%" PRIx64 " "
                  "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
                  "rbtr=%" PRIx64 "\n",
                  env->msr, env->esr, env->ear,
@@ -1866,7 +1866,7 @@ void mb_tcg_init(void)
     cpu_ear =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_esr =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr), "resr");
+        tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, esr), "resr");
     cpu_fsr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr), "rfsr");
     cpu_btr =
-- 
2.25.1



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

* [PATCH v2 16/76] target/microblaze: Fix width of FSR
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (14 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 15/76] target/microblaze: Fix width of ESR Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 17/76] target/microblaze: Fix width of BTR Richard Henderson
                   ` (60 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The exception status register is only 32-bits wide.  Do not use a
64-bit type to represent it.  Since cpu_fsr is only used during
MSR and MTR instructions, we can just as easily use an explicit
load and store, so eliminate the variable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  2 +-
 target/microblaze/translate.c | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index aaac0c9a6c..34177f9b28 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -240,7 +240,7 @@ struct CPUMBState {
     uint32_t msr;
     uint64_t ear;
     uint32_t esr;
-    uint64_t fsr;
+    uint32_t fsr;
     uint64_t btr;
     uint64_t edr;
     float_status fp_status;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index f63aae6de9..3fc2feda3d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -59,7 +59,6 @@ static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
 static TCGv_i64 cpu_ear;
 static TCGv_i32 cpu_esr;
-static TCGv_i64 cpu_fsr;
 static TCGv_i64 cpu_btr;
 static TCGv_i64 cpu_edr;
 static TCGv_i32 env_imm;
@@ -542,7 +541,8 @@ static void dec_msr(DisasContext *dc)
                 tcg_gen_mov_i32(cpu_esr, cpu_R[dc->ra]);
                 break;
             case SR_FSR:
-                tcg_gen_extu_i32_i64(cpu_fsr, cpu_R[dc->ra]);
+                tcg_gen_st_i32(cpu_R[dc->ra],
+                               cpu_env, offsetof(CPUMBState, fsr));
                 break;
             case SR_BTR:
                 tcg_gen_extu_i32_i64(cpu_btr, cpu_R[dc->ra]);
@@ -583,7 +583,8 @@ static void dec_msr(DisasContext *dc)
                 tcg_gen_mov_i32(cpu_R[dc->rd], cpu_esr);
                 break;
             case SR_FSR:
-                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_fsr);
+                tcg_gen_ld_i32(cpu_R[dc->rd],
+                               cpu_env, offsetof(CPUMBState, fsr));
                 break;
             case SR_BTR:
                 tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_btr);
@@ -1798,7 +1799,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, "IN: PC=%x %s\n",
                  env->pc, lookup_symbol(env->pc));
     qemu_fprintf(f, "rmsr=%x resr=%x rear=%" PRIx64 " "
-                 "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
+                 "debug=%x imm=%x iflags=%x fsr=%x "
                  "rbtr=%" PRIx64 "\n",
                  env->msr, env->esr, env->ear,
                  env->debug, env->imm, env->iflags, env->fsr,
@@ -1867,8 +1868,6 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_esr =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, esr), "resr");
-    cpu_fsr =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr), "rfsr");
     cpu_btr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, btr), "rbtr");
     cpu_edr =
-- 
2.25.1



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

* [PATCH v2 17/76] target/microblaze: Fix width of BTR
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (15 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 16/76] target/microblaze: Fix width of FSR Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 18/76] target/microblaze: Fix width of EDR Richard Henderson
                   ` (59 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The branch target register is only 32-bits wide.  Do not use a
64-bit type to represent it.  Since cpu_btr is only used during
MSR and MTR instructions, we can just as easily use an explicit
load and store, so eliminate the variable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  2 +-
 target/microblaze/translate.c | 12 +++++-------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 34177f9b28..72f068a5fd 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -241,7 +241,7 @@ struct CPUMBState {
     uint64_t ear;
     uint32_t esr;
     uint32_t fsr;
-    uint64_t btr;
+    uint32_t btr;
     uint64_t edr;
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 3fc2feda3d..a2bba0fe61 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -59,7 +59,6 @@ static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
 static TCGv_i64 cpu_ear;
 static TCGv_i32 cpu_esr;
-static TCGv_i64 cpu_btr;
 static TCGv_i64 cpu_edr;
 static TCGv_i32 env_imm;
 static TCGv_i32 env_btaken;
@@ -545,7 +544,8 @@ static void dec_msr(DisasContext *dc)
                                cpu_env, offsetof(CPUMBState, fsr));
                 break;
             case SR_BTR:
-                tcg_gen_extu_i32_i64(cpu_btr, cpu_R[dc->ra]);
+                tcg_gen_st_i32(cpu_R[dc->ra],
+                               cpu_env, offsetof(CPUMBState, btr));
                 break;
             case SR_EDR:
                 tcg_gen_extu_i32_i64(cpu_edr, cpu_R[dc->ra]);
@@ -587,7 +587,8 @@ static void dec_msr(DisasContext *dc)
                                cpu_env, offsetof(CPUMBState, fsr));
                 break;
             case SR_BTR:
-                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_btr);
+                tcg_gen_ld_i32(cpu_R[dc->rd],
+                               cpu_env, offsetof(CPUMBState, btr));
                 break;
             case SR_EDR:
                 tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_edr);
@@ -1799,8 +1800,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, "IN: PC=%x %s\n",
                  env->pc, lookup_symbol(env->pc));
     qemu_fprintf(f, "rmsr=%x resr=%x rear=%" PRIx64 " "
-                 "debug=%x imm=%x iflags=%x fsr=%x "
-                 "rbtr=%" PRIx64 "\n",
+                 "debug=%x imm=%x iflags=%x fsr=%x rbtr=%x\n",
                  env->msr, env->esr, env->ear,
                  env->debug, env->imm, env->iflags, env->fsr,
                  env->btr);
@@ -1868,8 +1868,6 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_esr =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, esr), "resr");
-    cpu_btr =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, btr), "rbtr");
     cpu_edr =
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, edr), "redr");
 }
-- 
2.25.1



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

* [PATCH v2 18/76] target/microblaze: Fix width of EDR
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (16 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 17/76] target/microblaze: Fix width of BTR Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 19/76] target/microblaze: Remove cpu_ear Richard Henderson
                   ` (58 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The exception data register is only 32-bits wide.  Do not use a
64-bit type to represent it.  Since cpu_edr is only used during
MSR and MTR instructions, we can just as easily use an explicit
load and store, so eliminate the variable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  2 +-
 target/microblaze/translate.c | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 72f068a5fd..b88acba12b 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -242,7 +242,7 @@ struct CPUMBState {
     uint32_t esr;
     uint32_t fsr;
     uint32_t btr;
-    uint64_t edr;
+    uint32_t edr;
     float_status fp_status;
     /* Stack protectors. Yes, it's a hw feature.  */
     uint32_t slr, shr;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a2bba0fe61..a862ac4055 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -59,7 +59,6 @@ static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
 static TCGv_i64 cpu_ear;
 static TCGv_i32 cpu_esr;
-static TCGv_i64 cpu_edr;
 static TCGv_i32 env_imm;
 static TCGv_i32 env_btaken;
 static TCGv_i32 cpu_btarget;
@@ -548,7 +547,8 @@ static void dec_msr(DisasContext *dc)
                                cpu_env, offsetof(CPUMBState, btr));
                 break;
             case SR_EDR:
-                tcg_gen_extu_i32_i64(cpu_edr, cpu_R[dc->ra]);
+                tcg_gen_st_i32(cpu_R[dc->ra],
+                               cpu_env, offsetof(CPUMBState, edr));
                 break;
             case 0x800:
                 tcg_gen_st_i32(cpu_R[dc->ra],
@@ -591,7 +591,8 @@ static void dec_msr(DisasContext *dc)
                                cpu_env, offsetof(CPUMBState, btr));
                 break;
             case SR_EDR:
-                tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_edr);
+                tcg_gen_ld_i32(cpu_R[dc->rd],
+                               cpu_env, offsetof(CPUMBState, edr));
                 break;
             case 0x800:
                 tcg_gen_ld_i32(cpu_R[dc->rd],
@@ -1818,7 +1819,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     }
 
     /* Registers that aren't modeled are reported as 0 */
-    qemu_fprintf(f, "redr=%" PRIx64 " rpid=0 rzpr=0 rtlbx=0 rtlbsx=0 "
+    qemu_fprintf(f, "redr=%x rpid=0 rzpr=0 rtlbx=0 rtlbsx=0 "
                     "rtlblo=0 rtlbhi=0\n", env->edr);
     qemu_fprintf(f, "slr=%x shr=%x\n", env->slr, env->shr);
     for (i = 0; i < 32; i++) {
@@ -1868,8 +1869,6 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_esr =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, esr), "resr");
-    cpu_edr =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, edr), "redr");
 }
 
 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
-- 
2.25.1



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

* [PATCH v2 19/76] target/microblaze: Remove cpu_ear
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (17 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 18/76] target/microblaze: Fix width of EDR Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 20/76] target/microblaze: Tidy raising of exceptions Richard Henderson
                   ` (57 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Since cpu_ear is only used during MSR and MTR instructions,
we can just as easily use an explicit load and store, so
eliminate the variable.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a862ac4055..f5ca25cead 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -57,7 +57,6 @@ static TCGv_i32 env_debug;
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
-static TCGv_i64 cpu_ear;
 static TCGv_i32 cpu_esr;
 static TCGv_i32 env_imm;
 static TCGv_i32 env_btaken;
@@ -533,7 +532,12 @@ static void dec_msr(DisasContext *dc)
                 msr_write(dc, cpu_R[dc->ra]);
                 break;
             case SR_EAR:
-                tcg_gen_extu_i32_i64(cpu_ear, cpu_R[dc->ra]);
+                {
+                    TCGv_i64 t64 = tcg_temp_new_i64();
+                    tcg_gen_extu_i32_i64(t64, cpu_R[dc->ra]);
+                    tcg_gen_st_i64(t64, cpu_env, offsetof(CPUMBState, ear));
+                    tcg_temp_free_i64(t64);
+                }
                 break;
             case SR_ESR:
                 tcg_gen_mov_i32(cpu_esr, cpu_R[dc->ra]);
@@ -573,10 +577,15 @@ static void dec_msr(DisasContext *dc)
                 msr_read(dc, cpu_R[dc->rd]);
                 break;
             case SR_EAR:
-                if (extended) {
-                    tcg_gen_extrh_i64_i32(cpu_R[dc->rd], cpu_ear);
-                } else {
-                    tcg_gen_extrl_i64_i32(cpu_R[dc->rd], cpu_ear);
+                {
+                    TCGv_i64 t64 = tcg_temp_new_i64();
+                    tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
+                    if (extended) {
+                        tcg_gen_extrh_i64_i32(cpu_R[dc->rd], t64);
+                    } else {
+                        tcg_gen_extrl_i64_i32(cpu_R[dc->rd], t64);
+                    }
+                    tcg_temp_free_i64(t64);
                 }
                 break;
             case SR_ESR:
@@ -1865,8 +1874,6 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, pc), "rpc");
     cpu_msr =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, msr), "rmsr");
-    cpu_ear =
-        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear), "rear");
     cpu_esr =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, esr), "resr");
 }
-- 
2.25.1



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

* [PATCH v2 20/76] target/microblaze: Tidy raising of exceptions
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (18 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 19/76] target/microblaze: Remove cpu_ear Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 21/76] target/microblaze: Mark raise_exception as noreturn Richard Henderson
                   ` (56 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Split out gen_raise_exception which does no cpu state sync.
Rename t_gen_raise_exception to gen_raise_exception_sync to
emphasize that it does a sync.  Create gen_raise_hw_excp to
simplify code raising EXCP_HW_EXCP.

Since there is now only one use of cpu_esr, perform a store
instead and remove the TCG variable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/translate.c | 62 +++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 25 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index f5ca25cead..9a00a78b8a 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -57,7 +57,6 @@ static TCGv_i32 env_debug;
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
-static TCGv_i32 cpu_esr;
 static TCGv_i32 env_imm;
 static TCGv_i32 env_btaken;
 static TCGv_i32 cpu_btarget;
@@ -114,17 +113,31 @@ static inline void t_sync_flags(DisasContext *dc)
     }
 }
 
-static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
+static void gen_raise_exception(DisasContext *dc, uint32_t index)
 {
     TCGv_i32 tmp = tcg_const_i32(index);
 
-    t_sync_flags(dc);
-    tcg_gen_movi_i32(cpu_pc, dc->pc);
     gen_helper_raise_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
     dc->is_jmp = DISAS_UPDATE;
 }
 
+static void gen_raise_exception_sync(DisasContext *dc, uint32_t index)
+{
+    t_sync_flags(dc);
+    tcg_gen_movi_i32(cpu_pc, dc->pc);
+    gen_raise_exception(dc, index);
+}
+
+static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
+{
+    TCGv_i32 tmp = tcg_const_i32(esr_ec);
+    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, esr));
+    tcg_temp_free_i32(tmp);
+
+    gen_raise_exception_sync(dc, EXCP_HW_EXCP);
+}
+
 static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
 {
 #ifndef CONFIG_USER_ONLY
@@ -178,8 +191,7 @@ static bool trap_illegal(DisasContext *dc, bool cond)
 {
     if (cond && (dc->tb_flags & MSR_EE_FLAG)
         && dc->cpu->cfg.illegal_opcode_exception) {
-        tcg_gen_movi_i32(cpu_esr, ESR_EC_ILLEGAL_OP);
-        t_gen_raise_exception(dc, EXCP_HW_EXCP);
+        gen_raise_hw_excp(dc, ESR_EC_ILLEGAL_OP);
     }
     return cond;
 }
@@ -194,8 +206,7 @@ static bool trap_userspace(DisasContext *dc, bool cond)
     bool cond_user = cond && mem_index == MMU_USER_IDX;
 
     if (cond_user && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_i32(cpu_esr, ESR_EC_PRIVINSN);
-        t_gen_raise_exception(dc, EXCP_HW_EXCP);
+        gen_raise_hw_excp(dc, ESR_EC_PRIVINSN);
     }
     return cond_user;
 }
@@ -540,7 +551,8 @@ static void dec_msr(DisasContext *dc)
                 }
                 break;
             case SR_ESR:
-                tcg_gen_mov_i32(cpu_esr, cpu_R[dc->ra]);
+                tcg_gen_st_i32(cpu_R[dc->ra],
+                               cpu_env, offsetof(CPUMBState, esr));
                 break;
             case SR_FSR:
                 tcg_gen_st_i32(cpu_R[dc->ra],
@@ -589,7 +601,8 @@ static void dec_msr(DisasContext *dc)
                 }
                 break;
             case SR_ESR:
-                tcg_gen_mov_i32(cpu_R[dc->rd], cpu_esr);
+                tcg_gen_ld_i32(cpu_R[dc->rd],
+                               cpu_env, offsetof(CPUMBState, esr));
                 break;
             case SR_FSR:
                 tcg_gen_ld_i32(cpu_R[dc->rd],
@@ -1258,8 +1271,7 @@ static void dec_br(DisasContext *dc)
 
         /* mbar IMM & 16 decodes to sleep.  */
         if (mbar_imm & 16) {
-            TCGv_i32 tmp_hlt = tcg_const_i32(EXCP_HLT);
-            TCGv_i32 tmp_1 = tcg_const_i32(1);
+            TCGv_i32 tmp_1;
 
             LOG_DIS("sleep\n");
 
@@ -1269,13 +1281,16 @@ static void dec_br(DisasContext *dc)
             }
 
             t_sync_flags(dc);
+
+            tmp_1 = tcg_const_i32(1);
             tcg_gen_st_i32(tmp_1, cpu_env,
                            -offsetof(MicroBlazeCPU, env)
                            +offsetof(CPUState, halted));
-            tcg_gen_movi_i32(cpu_pc, dc->pc + 4);
-            gen_helper_raise_exception(cpu_env, tmp_hlt);
-            tcg_temp_free_i32(tmp_hlt);
             tcg_temp_free_i32(tmp_1);
+
+            tcg_gen_movi_i32(cpu_pc, dc->pc + 4);
+
+            gen_raise_exception(dc, EXCP_HLT);
             return;
         }
         /* Break the TB.  */
@@ -1300,14 +1315,15 @@ static void dec_br(DisasContext *dc)
         tcg_gen_movi_i32(env_btaken, 1);
         tcg_gen_mov_i32(cpu_btarget, *(dec_alu_op_b(dc)));
         if (link && !dslot) {
-            if (!(dc->tb_flags & IMM_FLAG) && (dc->imm == 8 || dc->imm == 0x18))
-                t_gen_raise_exception(dc, EXCP_BREAK);
+            if (!(dc->tb_flags & IMM_FLAG) &&
+                (dc->imm == 8 || dc->imm == 0x18)) {
+                gen_raise_exception_sync(dc, EXCP_BREAK);
+            }
             if (dc->imm == 0) {
                 if (trap_userspace(dc, true)) {
                     return;
                 }
-
-                t_gen_raise_exception(dc, EXCP_DEBUG);
+                gen_raise_exception_sync(dc, EXCP_DEBUG);
             }
         }
     } else {
@@ -1411,8 +1427,7 @@ static void dec_rts(DisasContext *dc)
 static int dec_check_fpuv2(DisasContext *dc)
 {
     if ((dc->cpu->cfg.use_fpu != 2) && (dc->tb_flags & MSR_EE_FLAG)) {
-        tcg_gen_movi_i32(cpu_esr, ESR_EC_FPU);
-        t_gen_raise_exception(dc, EXCP_HW_EXCP);
+        gen_raise_hw_excp(dc, ESR_EC_FPU);
     }
     return (dc->cpu->cfg.use_fpu == 2) ? PVR2_USE_FPU2_MASK : 0;
 }
@@ -1668,8 +1683,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
 #endif
 
         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
-            t_gen_raise_exception(dc, EXCP_DEBUG);
-            dc->is_jmp = DISAS_UPDATE;
+            gen_raise_exception_sync(dc, EXCP_DEBUG);
             /* 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
@@ -1874,8 +1888,6 @@ void mb_tcg_init(void)
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, pc), "rpc");
     cpu_msr =
         tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, msr), "rmsr");
-    cpu_esr =
-        tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, esr), "resr");
 }
 
 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
-- 
2.25.1



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

* [PATCH v2 21/76] target/microblaze: Mark raise_exception as noreturn
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (19 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 20/76] target/microblaze: Tidy raising of exceptions Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 22/76] target/microblaze: Remove helper_debug and env->debug Richard Henderson
                   ` (55 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This will allow tcg to remove any dead code that might
follow an exception.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 2f8bdea22b..820711366d 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -1,4 +1,4 @@
-DEF_HELPER_2(raise_exception, void, env, i32)
+DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, i32)
 DEF_HELPER_1(debug, void, env)
 DEF_HELPER_FLAGS_3(carry, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_2(cmp, i32, i32, i32)
-- 
2.25.1



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

* [PATCH v2 22/76] target/microblaze: Remove helper_debug and env->debug
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (20 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 21/76] target/microblaze: Mark raise_exception as noreturn Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 23/76] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
                   ` (54 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This is not used, and seems redundant with -d cpu.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  1 -
 target/microblaze/helper.h    |  1 -
 target/microblaze/op_helper.c | 23 -----------------------
 target/microblaze/translate.c | 16 ++--------------
 4 files changed, 2 insertions(+), 39 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index b88acba12b..7708c9a3d3 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -229,7 +229,6 @@ typedef struct CPUMBState CPUMBState;
 #define STREAM_NONBLOCK  (1 << 4)
 
 struct CPUMBState {
-    uint32_t debug;
     uint32_t btaken;
     uint32_t btarget;
     uint32_t bimm;
diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 820711366d..9309142f8d 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -1,5 +1,4 @@
 DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, i32)
-DEF_HELPER_1(debug, void, env)
 DEF_HELPER_FLAGS_3(carry, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_2(cmp, i32, i32, i32)
 DEF_HELPER_2(cmpu, i32, i32, i32)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index dc2bec0c99..d79202c3f8 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -71,29 +71,6 @@ void helper_raise_exception(CPUMBState *env, uint32_t index)
     cpu_loop_exit(cs);
 }
 
-void helper_debug(CPUMBState *env)
-{
-    int i;
-
-    qemu_log("PC=%08x\n", env->pc);
-    qemu_log("rmsr=%x resr=%x rear=%" PRIx64 " "
-             "debug[%x] imm=%x iflags=%x\n",
-             env->msr, env->esr, env->ear,
-             env->debug, env->imm, env->iflags);
-    qemu_log("btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
-             env->btaken, env->btarget,
-             (env->msr & MSR_UM) ? "user" : "kernel",
-             (env->msr & MSR_UMS) ? "user" : "kernel",
-             (bool)(env->msr & MSR_EIP),
-             (bool)(env->msr & MSR_IE));
-    for (i = 0; i < 32; i++) {
-        qemu_log("r%2.2d=%8.8x ", i, env->regs[i]);
-        if ((i + 1) % 4 == 0)
-            qemu_log("\n");
-    }
-    qemu_log("\n\n");
-}
-
 static inline uint32_t compute_carry(uint32_t a, uint32_t b, uint32_t cin)
 {
     uint32_t cout = 0;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9a00a78b8a..ecfa6b86a4 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -53,7 +53,6 @@
 #define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
 #define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
 
-static TCGv_i32 env_debug;
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
@@ -1675,13 +1674,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
         tcg_gen_insn_start(dc->pc);
         num_insns++;
 
-#if SIM_COMPAT
-        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-            tcg_gen_movi_i32(cpu_pc, dc->pc);
-            gen_helper_debug();
-        }
-#endif
-
         if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
             gen_raise_exception_sync(dc, EXCP_DEBUG);
             /* The address covered by the breakpoint must be included in
@@ -1824,10 +1816,9 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, "IN: PC=%x %s\n",
                  env->pc, lookup_symbol(env->pc));
     qemu_fprintf(f, "rmsr=%x resr=%x rear=%" PRIx64 " "
-                 "debug=%x imm=%x iflags=%x fsr=%x rbtr=%x\n",
+                 "imm=%x iflags=%x fsr=%x rbtr=%x\n",
                  env->msr, env->esr, env->ear,
-                 env->debug, env->imm, env->iflags, env->fsr,
-                 env->btr);
+                 env->imm, env->iflags, env->fsr, env->btr);
     qemu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
                  env->btaken, env->btarget,
                  (env->msr & MSR_UM) ? "user" : "kernel",
@@ -1857,9 +1848,6 @@ void mb_tcg_init(void)
 {
     int i;
 
-    env_debug = tcg_global_mem_new_i32(cpu_env,
-                    offsetof(CPUMBState, debug),
-                    "debug0");
     env_iflags = tcg_global_mem_new_i32(cpu_env,
                     offsetof(CPUMBState, iflags),
                     "iflags");
-- 
2.25.1



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

* [PATCH v2 23/76] target/microblaze: Rename env_* tcg variables to cpu_*
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (21 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 22/76] target/microblaze: Remove helper_debug and env->debug Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 21:11   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 24/76] target/microblaze: Tidy mb_tcg_init Richard Henderson
                   ` (53 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This is cpu_imm, cpu_btaken, cpu_iflags, cpu_res_addr and cpu_res_val.
It is standard for these file-scope globals to begin with cpu_*.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index ecfa6b86a4..9aa63ddcc5 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -56,12 +56,12 @@
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
-static TCGv_i32 env_imm;
-static TCGv_i32 env_btaken;
+static TCGv_i32 cpu_imm;
+static TCGv_i32 cpu_btaken;
 static TCGv_i32 cpu_btarget;
-static TCGv_i32 env_iflags;
-static TCGv env_res_addr;
-static TCGv_i32 env_res_val;
+static TCGv_i32 cpu_iflags;
+static TCGv cpu_res_addr;
+static TCGv_i32 cpu_res_val;
 
 #include "exec/gen-icount.h"
 
@@ -107,7 +107,7 @@ static inline void t_sync_flags(DisasContext *dc)
 {
     /* Synch the tb dependent flags between translator and runtime.  */
     if (dc->tb_flags != dc->synced_flags) {
-        tcg_gen_movi_i32(env_iflags, dc->tb_flags);
+        tcg_gen_movi_i32(cpu_iflags, dc->tb_flags);
         dc->synced_flags = dc->tb_flags;
     }
 }
@@ -222,10 +222,10 @@ static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
 {
     if (dc->type_b) {
         if (dc->tb_flags & IMM_FLAG)
-            tcg_gen_ori_i32(env_imm, env_imm, dc->imm);
+            tcg_gen_ori_i32(cpu_imm, cpu_imm, dc->imm);
         else
-            tcg_gen_movi_i32(env_imm, (int32_t)((int16_t)dc->imm));
-        return &env_imm;
+            tcg_gen_movi_i32(cpu_imm, (int32_t)((int16_t)dc->imm));
+        return &cpu_imm;
     } else
         return &cpu_R[dc->rb];
 }
@@ -859,7 +859,7 @@ static inline void sync_jmpstate(DisasContext *dc)
 {
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
         if (dc->jmp == JMP_DIRECT) {
-            tcg_gen_movi_i32(env_btaken, 1);
+            tcg_gen_movi_i32(cpu_btaken, 1);
         }
         dc->jmp = JMP_INDIRECT;
         tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
@@ -869,7 +869,7 @@ static inline void sync_jmpstate(DisasContext *dc)
 static void dec_imm(DisasContext *dc)
 {
     LOG_DIS("imm %x\n", dc->imm << 16);
-    tcg_gen_movi_i32(env_imm, (dc->imm << 16));
+    tcg_gen_movi_i32(cpu_imm, (dc->imm << 16));
     dc->tb_flags |= IMM_FLAG;
     dc->clear_imm = 0;
 }
@@ -1040,8 +1040,8 @@ static void dec_load(DisasContext *dc)
     }
 
     if (ex) {
-        tcg_gen_mov_tl(env_res_addr, addr);
-        tcg_gen_mov_i32(env_res_val, v);
+        tcg_gen_mov_tl(cpu_res_addr, addr);
+        tcg_gen_mov_i32(cpu_res_val, v);
     }
     if (dc->rd) {
         tcg_gen_mov_i32(cpu_R[dc->rd], v);
@@ -1103,7 +1103,7 @@ static void dec_store(DisasContext *dc)
 
         write_carryi(dc, 1);
         swx_skip = gen_new_label();
-        tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, addr, swx_skip);
+        tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_skip);
 
         /*
          * Compare the value loaded at lwx with current contents of
@@ -1111,11 +1111,11 @@ static void dec_store(DisasContext *dc)
          */
         tval = tcg_temp_new_i32();
 
-        tcg_gen_atomic_cmpxchg_i32(tval, addr, env_res_val,
+        tcg_gen_atomic_cmpxchg_i32(tval, addr, cpu_res_val,
                                    cpu_R[dc->rd], mem_index,
                                    mop);
 
-        tcg_gen_brcond_i32(TCG_COND_NE, env_res_val, tval, swx_skip);
+        tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_skip);
         write_carryi(dc, 0);
         tcg_temp_free_i32(tval);
     }
@@ -1204,7 +1204,7 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i32 pc_true, TCGv_i32 pc_false)
     TCGv_i32 zero = tcg_const_i32(0);
 
     tcg_gen_movcond_i32(TCG_COND_NE, cpu_pc,
-                        env_btaken, zero,
+                        cpu_btaken, zero,
                         pc_true, pc_false);
 
     tcg_temp_free_i32(zero);
@@ -1245,7 +1245,7 @@ static void dec_bcc(DisasContext *dc)
         dc->jmp = JMP_INDIRECT;
         tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
     }
-    eval_cc(dc, cc, env_btaken, cpu_R[dc->ra]);
+    eval_cc(dc, cc, cpu_btaken, cpu_R[dc->ra]);
 }
 
 static void dec_br(DisasContext *dc)
@@ -1311,7 +1311,7 @@ static void dec_br(DisasContext *dc)
 
     dc->jmp = JMP_INDIRECT;
     if (abs) {
-        tcg_gen_movi_i32(env_btaken, 1);
+        tcg_gen_movi_i32(cpu_btaken, 1);
         tcg_gen_mov_i32(cpu_btarget, *(dec_alu_op_b(dc)));
         if (link && !dslot) {
             if (!(dc->tb_flags & IMM_FLAG) &&
@@ -1330,7 +1330,7 @@ static void dec_br(DisasContext *dc)
             dc->jmp = JMP_DIRECT;
             dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
         } else {
-            tcg_gen_movi_i32(env_btaken, 1);
+            tcg_gen_movi_i32(cpu_btaken, 1);
             tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
         }
     }
@@ -1419,7 +1419,7 @@ static void dec_rts(DisasContext *dc)
         LOG_DIS("rts ir=%x\n", dc->ir);
 
     dc->jmp = JMP_INDIRECT;
-    tcg_gen_movi_i32(env_btaken, 1);
+    tcg_gen_movi_i32(cpu_btaken, 1);
     tcg_gen_add_i32(cpu_btarget, cpu_R[dc->ra], *dec_alu_op_b(dc));
 }
 
@@ -1722,7 +1722,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                     TCGLabel *l1 = gen_new_label();
                     t_sync_flags(dc);
                     /* Conditional jmp.  */
-                    tcg_gen_brcondi_i32(TCG_COND_NE, env_btaken, 0, l1);
+                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_btaken, 0, l1);
                     gen_goto_tb(dc, 1, dc->pc);
                     gen_set_label(l1);
                     gen_goto_tb(dc, 0, dc->jmp_pc);
@@ -1848,22 +1848,22 @@ void mb_tcg_init(void)
 {
     int i;
 
-    env_iflags = tcg_global_mem_new_i32(cpu_env,
+    cpu_iflags = tcg_global_mem_new_i32(cpu_env,
                     offsetof(CPUMBState, iflags),
                     "iflags");
-    env_imm = tcg_global_mem_new_i32(cpu_env,
+    cpu_imm = tcg_global_mem_new_i32(cpu_env,
                     offsetof(CPUMBState, imm),
                     "imm");
     cpu_btarget = tcg_global_mem_new_i32(cpu_env,
                      offsetof(CPUMBState, btarget),
                      "btarget");
-    env_btaken = tcg_global_mem_new_i32(cpu_env,
+    cpu_btaken = tcg_global_mem_new_i32(cpu_env,
                      offsetof(CPUMBState, btaken),
                      "btaken");
-    env_res_addr = tcg_global_mem_new(cpu_env,
+    cpu_res_addr = tcg_global_mem_new(cpu_env,
                      offsetof(CPUMBState, res_addr),
                      "res_addr");
-    env_res_val = tcg_global_mem_new_i32(cpu_env,
+    cpu_res_val = tcg_global_mem_new_i32(cpu_env,
                      offsetof(CPUMBState, res_val),
                      "res_val");
     for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
-- 
2.25.1



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

* [PATCH v2 24/76] target/microblaze: Tidy mb_tcg_init
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (22 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 23/76] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 25/76] target/microblaze: Split out MSR[C] to its own variable Richard Henderson
                   ` (52 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

All of the tcg globals can be recorded in the same table.
Drop the "r" prefix from "rpc" and "rmsr".  Obviates the
need for regnames[], which was incorrectly not const.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/translate.c | 62 +++++++++++++++--------------------
 1 file changed, 27 insertions(+), 35 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9aa63ddcc5..e709884f2d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -95,14 +95,6 @@ typedef struct DisasContext {
     int singlestep_enabled;
 } DisasContext;
 
-static const char *regnames[] =
-{
-    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
-    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
-    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
-};
-
 static inline void t_sync_flags(DisasContext *dc)
 {
     /* Synch the tb dependent flags between translator and runtime.  */
@@ -1846,36 +1838,36 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 
 void mb_tcg_init(void)
 {
-    int i;
+#define R(X)  { &cpu_R[X], offsetof(CPUMBState, regs[X]), "r" #X }
+#define SP(X) { &cpu_##X, offsetof(CPUMBState, X), #X }
 
-    cpu_iflags = tcg_global_mem_new_i32(cpu_env,
-                    offsetof(CPUMBState, iflags),
-                    "iflags");
-    cpu_imm = tcg_global_mem_new_i32(cpu_env,
-                    offsetof(CPUMBState, imm),
-                    "imm");
-    cpu_btarget = tcg_global_mem_new_i32(cpu_env,
-                     offsetof(CPUMBState, btarget),
-                     "btarget");
-    cpu_btaken = tcg_global_mem_new_i32(cpu_env,
-                     offsetof(CPUMBState, btaken),
-                     "btaken");
-    cpu_res_addr = tcg_global_mem_new(cpu_env,
-                     offsetof(CPUMBState, res_addr),
-                     "res_addr");
-    cpu_res_val = tcg_global_mem_new_i32(cpu_env,
-                     offsetof(CPUMBState, res_val),
-                     "res_val");
-    for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
-        cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
-                          offsetof(CPUMBState, regs[i]),
-                          regnames[i]);
+    static const struct {
+        TCGv_i32 *var; int ofs; char name[8];
+    } i32s[] = {
+        R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
+        R(8),  R(9),  R(10), R(11), R(12), R(13), R(14), R(15),
+        R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
+        R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
+
+        SP(pc),
+        SP(msr),
+        SP(imm),
+        SP(iflags),
+        SP(btaken),
+        SP(btarget),
+        SP(res_val),
+    };
+
+#undef R
+#undef SP
+
+    for (int i = 0; i < ARRAY_SIZE(i32s); ++i) {
+        *i32s[i].var =
+          tcg_global_mem_new_i32(cpu_env, i32s[i].ofs, i32s[i].name);
     }
 
-    cpu_pc =
-        tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, pc), "rpc");
-    cpu_msr =
-        tcg_global_mem_new_i32(cpu_env, offsetof(CPUMBState, msr), "rmsr");
+    cpu_res_addr =
+        tcg_global_mem_new(cpu_env, offsetof(CPUMBState, res_addr), "res_addr");
 }
 
 void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
-- 
2.25.1



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

* [PATCH v2 25/76] target/microblaze: Split out MSR[C] to its own variable
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (23 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 24/76] target/microblaze: Tidy mb_tcg_init Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 26/76] target/microblaze: Use DISAS_NORETURN Richard Henderson
                   ` (51 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Having the MSR[C] bit separate will improve arithmetic that operates
on the carry bit.  Having mb_cpu_read_msr() populate MSR[CC] will
prevent the carry copy not matching the carry bit.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       | 19 +++++++-
 linux-user/elfload.c          |  2 +-
 target/microblaze/cpu.c       |  4 +-
 target/microblaze/gdbstub.c   |  4 +-
 target/microblaze/helper.c    | 58 +++++++++++-----------
 target/microblaze/translate.c | 91 +++++++++++------------------------
 6 files changed, 82 insertions(+), 96 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 7708c9a3d3..7066878ac7 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -236,7 +236,8 @@ struct CPUMBState {
     uint32_t imm;
     uint32_t regs[32];
     uint32_t pc;
-    uint32_t msr;
+    uint32_t msr;    /* All bits of MSR except MSR[C] and MSR[CC] */
+    uint32_t msr_c;  /* MSR[C], in low bit; other bits must be 0 */
     uint64_t ear;
     uint32_t esr;
     uint32_t fsr;
@@ -327,6 +328,22 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
+static inline uint32_t mb_cpu_read_msr(const CPUMBState *env)
+{
+    /* Replicate MSR[C] to MSR[CC]. */
+    return env->msr | (env->msr_c * (MSR_C | MSR_CC));
+}
+
+static inline void mb_cpu_write_msr(CPUMBState *env, uint32_t val)
+{
+    env->msr_c = (val >> 2) & 1;
+    /*
+     * Clear both MSR[C] and MSR[CC] from the saved copy.
+     * MSR_PVR is not writable and is always clear.
+     */
+    env->msr = val & ~(MSR_C | MSR_CC | MSR_PVR);
+}
+
 void mb_tcg_init(void);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index bbfb665321..98af4fe7e0 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1033,7 +1033,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
     }
 
     (*regs)[pos++] = tswapreg(env->pc);
-    (*regs)[pos++] = tswapreg(env->msr);
+    (*regs)[pos++] = tswapreg(mb_cpu_read_msr(env));
     (*regs)[pos++] = 0;
     (*regs)[pos++] = tswapreg(env->ear);
     (*regs)[pos++] = 0;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 0eac068570..1eabf5cc3f 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -121,9 +121,9 @@ static void mb_cpu_reset(DeviceState *dev)
 
 #if defined(CONFIG_USER_ONLY)
     /* start in user mode with interrupts enabled.  */
-    env->msr = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
+    mb_cpu_write_msr(env, MSR_EE | MSR_IE | MSR_VM | MSR_UM);
 #else
-    env->msr = 0;
+    mb_cpu_write_msr(env, 0);
     mmu_init(&env->mmu);
     env->mmu.c_mmu = 3;
     env->mmu.c_mmu_tlb_access = 3;
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 9cba9d2215..08d6a0e807 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -62,7 +62,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
         val = env->pc;
         break;
     case GDB_MSR:
-        val = env->msr;
+        val = mb_cpu_read_msr(env);
         break;
     case GDB_EAR:
         val = env->ear;
@@ -118,7 +118,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         env->pc = tmp;
         break;
     case GDB_MSR:
-        env->msr = tmp;
+        mb_cpu_write_msr(env, tmp);
         break;
     case GDB_EAR:
         env->ear = tmp;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index b2373f6a23..9a95456401 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -112,12 +112,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
-    uint32_t t;
+    uint32_t t, msr = mb_cpu_read_msr(env);
 
     /* IMM flag cannot propagate across a branch and into the dslot.  */
     assert(!((env->iflags & D_FLAG) && (env->iflags & IMM_FLAG)));
     assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
-/*    assert(env->msr & (MSR_EE)); Only for HW exceptions.  */
     env->res_addr = RES_ADDR_NONE;
     switch (cs->exception_index) {
         case EXCP_HW_EXCP:
@@ -136,11 +135,12 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 
             /* Disable the MMU.  */
-            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
-            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
-            env->msr |= t;
+            t = (msr & (MSR_VM | MSR_UM)) << 1;
+            msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+            msr |= t;
             /* Exception in progress.  */
-            env->msr |= MSR_EIP;
+            msr |= MSR_EIP;
+            mb_cpu_write_msr(env, msr);
 
             qemu_log_mask(CPU_LOG_INT,
                           "hw exception at pc=%x ear=%" PRIx64 " "
@@ -178,11 +178,12 @@ void mb_cpu_do_interrupt(CPUState *cs)
             }
 
             /* Disable the MMU.  */
-            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
-            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
-            env->msr |= t;
+            t = (msr & (MSR_VM | MSR_UM)) << 1;
+            msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+            msr |= t;
             /* Exception in progress.  */
-            env->msr |= MSR_EIP;
+            msr |= MSR_EIP;
+            mb_cpu_write_msr(env, msr);
 
             qemu_log_mask(CPU_LOG_INT,
                           "exception at pc=%x ear=%" PRIx64 " iflags=%x\n",
@@ -193,11 +194,11 @@ void mb_cpu_do_interrupt(CPUState *cs)
             break;
 
         case EXCP_IRQ:
-            assert(!(env->msr & (MSR_EIP | MSR_BIP)));
-            assert(env->msr & MSR_IE);
+            assert(!(msr & (MSR_EIP | MSR_BIP)));
+            assert(msr & MSR_IE);
             assert(!(env->iflags & D_FLAG));
 
-            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
+            t = (msr & (MSR_VM | MSR_UM)) << 1;
 
 #if 0
 #include "disas/disas.h"
@@ -212,21 +213,20 @@ void mb_cpu_do_interrupt(CPUState *cs)
                     && (!strcmp("netif_rx", sym)
                         || !strcmp("process_backlog", sym))) {
 
-                    qemu_log(
-                         "interrupt at pc=%x msr=%x %x iflags=%x sym=%s\n",
-                         env->pc, env->msr, t, env->iflags,
-                         sym);
+                    qemu_log("interrupt at pc=%x msr=%x %x iflags=%x sym=%s\n",
+                             env->pc, msr, t, env->iflags, sym);
 
                     log_cpu_state(cs, 0);
                 }
             }
 #endif
             qemu_log_mask(CPU_LOG_INT,
-                         "interrupt at pc=%x msr=%x %x iflags=%x\n",
-                         env->pc, env->msr, t, env->iflags);
+                          "interrupt at pc=%x msr=%x %x iflags=%x\n",
+                          env->pc, msr, t, env->iflags);
 
-            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE);
-            env->msr |= t;
+            msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE);
+            msr |= t;
+            mb_cpu_write_msr(env, msr);
 
             env->regs[14] = env->pc;
             env->pc = cpu->cfg.base_vectors + 0x10;
@@ -237,20 +237,22 @@ void mb_cpu_do_interrupt(CPUState *cs)
         case EXCP_HW_BREAK:
             assert(!(env->iflags & IMM_FLAG));
             assert(!(env->iflags & D_FLAG));
-            t = (env->msr & (MSR_VM | MSR_UM)) << 1;
+            t = (msr & (MSR_VM | MSR_UM)) << 1;
             qemu_log_mask(CPU_LOG_INT,
                           "break at pc=%x msr=%x %x iflags=%x\n",
-                          env->pc, env->msr, t, env->iflags);
+                          env->pc, msr, t, env->iflags);
             log_cpu_state_mask(CPU_LOG_INT, cs, 0);
-            env->msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
-            env->msr |= t;
-            env->msr |= MSR_BIP;
+            msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
+            msr |= t;
+            msr |= MSR_BIP;
             if (cs->exception_index == EXCP_HW_BREAK) {
                 env->regs[16] = env->pc;
-                env->msr |= MSR_BIP;
+                msr |= MSR_BIP;
                 env->pc = cpu->cfg.base_vectors + 0x18;
-            } else
+            } else {
                 env->pc = env->btarget;
+            }
+            mb_cpu_write_msr(env, msr);
             break;
         default:
             cpu_abort(cs, "unhandled exception type=%d\n",
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index e709884f2d..0c9b4ffa5a 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -56,6 +56,7 @@
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
+static TCGv_i32 cpu_msr_c;
 static TCGv_i32 cpu_imm;
 static TCGv_i32 cpu_btaken;
 static TCGv_i32 cpu_btarget;
@@ -150,30 +151,6 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
     }
 }
 
-static void read_carry(DisasContext *dc, TCGv_i32 d)
-{
-    tcg_gen_shri_i32(d, cpu_msr, 31);
-}
-
-/*
- * write_carry sets the carry bits in MSR based on bit 0 of v.
- * v[31:1] are ignored.
- */
-static void write_carry(DisasContext *dc, TCGv_i32 v)
-{
-    /* Deposit bit 0 into MSR_C and the alias MSR_CC.  */
-    tcg_gen_deposit_i32(cpu_msr, cpu_msr, v, 2, 1);
-    tcg_gen_deposit_i32(cpu_msr, cpu_msr, v, 31, 1);
-}
-
-static void write_carryi(DisasContext *dc, bool carry)
-{
-    TCGv_i32 t0 = tcg_temp_new_i32();
-    tcg_gen_movi_i32(t0, carry);
-    write_carry(dc, t0);
-    tcg_temp_free_i32(t0);
-}
-
 /*
  * Returns true if the insn an illegal operation.
  * If exceptions are enabled, an exception is raised.
@@ -243,11 +220,7 @@ static void dec_add(DisasContext *dc)
 
             if (c) {
                 /* c - Add carry into the result.  */
-                cf = tcg_temp_new_i32();
-
-                read_carry(dc, cf);
-                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-                tcg_temp_free_i32(cf);
+                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_msr_c);
             }
         }
         return;
@@ -257,21 +230,15 @@ static void dec_add(DisasContext *dc)
     /* Extract carry.  */
     cf = tcg_temp_new_i32();
     if (c) {
-        read_carry(dc, cf);
+        tcg_gen_mov_i32(cf, cpu_msr_c);
     } else {
         tcg_gen_movi_i32(cf, 0);
     }
 
+    gen_helper_carry(cpu_msr_c, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
     if (dc->rd) {
-        TCGv_i32 ncf = tcg_temp_new_i32();
-        gen_helper_carry(ncf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
         tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
         tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-        write_carry(dc, ncf);
-        tcg_temp_free_i32(ncf);
-    } else {
-        gen_helper_carry(cf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
-        write_carry(dc, cf);
     }
     tcg_temp_free_i32(cf);
 }
@@ -309,11 +276,7 @@ static void dec_sub(DisasContext *dc)
 
             if (c) {
                 /* c - Add carry into the result.  */
-                cf = tcg_temp_new_i32();
-
-                read_carry(dc, cf);
-                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-                tcg_temp_free_i32(cf);
+                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_msr_c);
             }
         }
         return;
@@ -324,7 +287,7 @@ static void dec_sub(DisasContext *dc)
     cf = tcg_temp_new_i32();
     na = tcg_temp_new_i32();
     if (c) {
-        read_carry(dc, cf);
+        tcg_gen_mov_i32(cf, cpu_msr_c);
     } else {
         tcg_gen_movi_i32(cf, 1);
     }
@@ -332,16 +295,10 @@ static void dec_sub(DisasContext *dc)
     /* d = b + ~a + c. carry defaults to 1.  */
     tcg_gen_not_i32(na, cpu_R[dc->ra]);
 
+    gen_helper_carry(cpu_msr_c, na, *(dec_alu_op_b(dc)), cf);
     if (dc->rd) {
-        TCGv_i32 ncf = tcg_temp_new_i32();
-        gen_helper_carry(ncf, na, *(dec_alu_op_b(dc)), cf);
         tcg_gen_add_i32(cpu_R[dc->rd], na, *(dec_alu_op_b(dc)));
         tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-        write_carry(dc, ncf);
-        tcg_temp_free_i32(ncf);
-    } else {
-        gen_helper_carry(cf, na, *(dec_alu_op_b(dc)), cf);
-        write_carry(dc, cf);
     }
     tcg_temp_free_i32(cf);
     tcg_temp_free_i32(na);
@@ -429,16 +386,26 @@ static void dec_xor(DisasContext *dc)
         tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
 
-static inline void msr_read(DisasContext *dc, TCGv_i32 d)
+static void msr_read(DisasContext *dc, TCGv_i32 d)
 {
-    tcg_gen_mov_i32(d, cpu_msr);
+    TCGv_i32 t;
+
+    /* Replicate the cpu_msr_c boolean into the proper bit and the copy. */
+    t = tcg_temp_new_i32();
+    tcg_gen_muli_i32(t, cpu_msr_c, MSR_C | MSR_CC);
+    tcg_gen_or_i32(d, cpu_msr, t);
+    tcg_temp_free_i32(t);
 }
 
-static inline void msr_write(DisasContext *dc, TCGv_i32 v)
+static void msr_write(DisasContext *dc, TCGv_i32 v)
 {
     dc->cpustate_changed = 1;
-    /* PVR bit is not writable, and is never set. */
-    tcg_gen_andi_i32(cpu_msr, v, ~MSR_PVR);
+
+    /* Install MSR_C.  */
+    tcg_gen_extract_i32(cpu_msr_c, v, 2, 1);
+
+    /* Clear MSR_C and MSR_CC; MSR_PVR is not writable, and is always clear. */
+    tcg_gen_andi_i32(cpu_msr, v, ~(MSR_C | MSR_CC | MSR_PVR));
 }
 
 static void dec_msr(DisasContext *dc)
@@ -778,8 +745,8 @@ static void dec_bit(DisasContext *dc)
             t0 = tcg_temp_new_i32();
 
             LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
-            tcg_gen_andi_i32(t0, cpu_msr, MSR_CC);
-            write_carry(dc, cpu_R[dc->ra]);
+            tcg_gen_shli_i32(t0, cpu_msr_c, 31);
+            tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1);
             if (dc->rd) {
                 tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                 tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->rd], t0);
@@ -792,8 +759,7 @@ static void dec_bit(DisasContext *dc)
             /* srl.  */
             LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
 
-            /* Update carry. Note that write carry only looks at the LSB.  */
-            write_carry(dc, cpu_R[dc->ra]);
+            tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1);
             if (dc->rd) {
                 if (op == 0x41)
                     tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
@@ -1042,7 +1008,7 @@ static void dec_load(DisasContext *dc)
 
     if (ex) { /* lwx */
         /* no support for AXI exclusive so always clear C */
-        write_carryi(dc, 0);
+        tcg_gen_movi_i32(cpu_msr_c, 0);
     }
 
     tcg_temp_free(addr);
@@ -1093,7 +1059,7 @@ static void dec_store(DisasContext *dc)
         /* swx does not throw unaligned access errors, so force alignment */
         tcg_gen_andi_tl(addr, addr, ~3);
 
-        write_carryi(dc, 1);
+        tcg_gen_movi_i32(cpu_msr_c, 1);
         swx_skip = gen_new_label();
         tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_skip);
 
@@ -1108,7 +1074,7 @@ static void dec_store(DisasContext *dc)
                                    mop);
 
         tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_skip);
-        write_carryi(dc, 0);
+        tcg_gen_movi_i32(cpu_msr_c, 0);
         tcg_temp_free_i32(tval);
     }
 
@@ -1851,6 +1817,7 @@ void mb_tcg_init(void)
 
         SP(pc),
         SP(msr),
+        SP(msr_c),
         SP(imm),
         SP(iflags),
         SP(btaken),
-- 
2.25.1



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

* [PATCH v2 26/76] target/microblaze: Use DISAS_NORETURN
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (24 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 25/76] target/microblaze: Split out MSR[C] to its own variable Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
                   ` (50 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Both exceptions and gen_goto_tb do not return.  Use the
official DISAS_NORETURN enumerator for this case.
This eliminates all use of DISAS_TB_JUMP.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 0c9b4ffa5a..53ca0bfb38 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -51,7 +51,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 */
 
 static TCGv_i32 cpu_R[32];
 static TCGv_i32 cpu_pc;
@@ -111,7 +110,7 @@ static void gen_raise_exception(DisasContext *dc, uint32_t index)
 
     gen_helper_raise_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
-    dc->is_jmp = DISAS_UPDATE;
+    dc->is_jmp = DISAS_NORETURN;
 }
 
 static void gen_raise_exception_sync(DisasContext *dc, uint32_t index)
@@ -149,6 +148,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
         tcg_gen_movi_i32(cpu_pc, dest);
         tcg_gen_exit_tb(NULL, 0);
     }
+    dc->is_jmp = DISAS_NORETURN;
 }
 
 /*
@@ -1675,7 +1675,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                 } else if (dc->jmp == JMP_DIRECT) {
                     t_sync_flags(dc);
                     gen_goto_tb(dc, 0, dc->jmp_pc);
-                    dc->is_jmp = DISAS_TB_JUMP;
                 } else if (dc->jmp == JMP_DIRECT_CC) {
                     TCGLabel *l1 = gen_new_label();
                     t_sync_flags(dc);
@@ -1684,8 +1683,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                     gen_goto_tb(dc, 1, dc->pc);
                     gen_set_label(l1);
                     gen_goto_tb(dc, 0, dc->jmp_pc);
-
-                    dc->is_jmp = DISAS_TB_JUMP;
                 }
                 break;
             }
@@ -1717,7 +1714,9 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     }
     t_sync_flags(dc);
 
-    if (unlikely(cs->singlestep_enabled)) {
+    if (dc->is_jmp == DISAS_NORETURN) {
+        /* nothing more to generate */
+    } else if (unlikely(cs->singlestep_enabled)) {
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
@@ -1730,16 +1729,14 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
             case DISAS_NEXT:
                 gen_goto_tb(dc, 1, npc);
                 break;
-            default:
             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_TB_JUMP:
-                /* nothing more to generate */
-                break;
+            default:
+                g_assert_not_reached();
         }
     }
     gen_tb_end(tb, num_insns);
-- 
2.25.1



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

* [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (25 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 26/76] target/microblaze: Use DISAS_NORETURN Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 13:54   ` Edgar E. Iglesias
  2020-08-28 14:18 ` [PATCH v2 28/76] target/microblaze: Convert to DisasContextBase Richard Henderson
                   ` (49 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Do not use goto_tb if we're single-stepping.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 53ca0bfb38..7d5b96c38b 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -140,7 +140,12 @@ static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
 
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-    if (use_goto_tb(dc, dest)) {
+    if (dc->singlestep_enabled) {
+        TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
+        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);
+        gen_helper_raise_exception(cpu_env, tmp);
+        tcg_temp_free_i32(tmp);
+    } else if (use_goto_tb(dc, dest)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
         tcg_gen_exit_tb(dc->tb, n);
-- 
2.25.1



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

* [PATCH v2 28/76] target/microblaze: Convert to DisasContextBase
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (26 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 29/76] target/microblaze: Convert to translator_loop Richard Henderson
                   ` (48 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Part one of conversion to the generic translator_loop is to
use the DisasContextBase and the members therein.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 7d5b96c38b..45b1555f85 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -67,8 +67,8 @@ static TCGv_i32 cpu_res_val;
 
 /* This is the state at translation time.  */
 typedef struct DisasContext {
+    DisasContextBase base;
     MicroBlazeCPU *cpu;
-    uint32_t pc;
 
     /* Decoder.  */
     int type_b;
@@ -81,7 +81,6 @@ typedef struct DisasContext {
     unsigned int delayed_branch;
     unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
     unsigned int clear_imm;
-    int is_jmp;
 
 #define JMP_NOJMP     0
 #define JMP_DIRECT    1
@@ -91,8 +90,6 @@ typedef struct DisasContext {
     uint32_t jmp_pc;
 
     int abort_at_next_insn;
-    struct TranslationBlock *tb;
-    int singlestep_enabled;
 } DisasContext;
 
 static inline void t_sync_flags(DisasContext *dc)
@@ -110,13 +107,13 @@ static void gen_raise_exception(DisasContext *dc, uint32_t index)
 
     gen_helper_raise_exception(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
-    dc->is_jmp = DISAS_NORETURN;
+    dc->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_raise_exception_sync(DisasContext *dc, uint32_t index)
 {
     t_sync_flags(dc);
-    tcg_gen_movi_i32(cpu_pc, dc->pc);
+    tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
     gen_raise_exception(dc, index);
 }
 
@@ -132,7 +129,7 @@ static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
 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);
 #else
     return true;
 #endif
@@ -140,20 +137,20 @@ static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
 
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
-    if (dc->singlestep_enabled) {
+    if (dc->base.singlestep_enabled) {
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
-        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);
+        tcg_gen_movi_i32(cpu_pc, dest);
         gen_helper_raise_exception(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
     } else if (use_goto_tb(dc, dest)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
-        tcg_gen_exit_tb(dc->tb, n);
+        tcg_gen_exit_tb(dc->base.tb, n);
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         tcg_gen_exit_tb(NULL, 0);
     }
-    dc->is_jmp = DISAS_NORETURN;
+    dc->base.is_jmp = DISAS_NORETURN;
 }
 
 /*
@@ -468,8 +465,8 @@ static void dec_msr(DisasContext *dc)
         msr_write(dc, t0);
         tcg_temp_free_i32(t0);
         tcg_temp_free_i32(t1);
-        tcg_gen_movi_i32(cpu_pc, dc->pc + 4);
-        dc->is_jmp = DISAS_UPDATE;
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
+        dc->base.is_jmp = DISAS_UPDATE;
         return;
     }
 
@@ -546,7 +543,7 @@ static void dec_msr(DisasContext *dc)
 
         switch (sr) {
             case SR_PC:
-                tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
+                tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
                 break;
             case SR_MSR:
                 msr_read(dc, cpu_R[dc->rd]);
@@ -813,7 +810,7 @@ static void dec_bit(DisasContext *dc)
             break;
         default:
             cpu_abort(cs, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
-                      dc->pc, op, dc->rd, dc->ra, dc->rb);
+                      (uint32_t)dc->base.pc_next, op, dc->rd, dc->ra, dc->rb);
             break;
     }
 }
@@ -994,7 +991,7 @@ static void dec_load(DisasContext *dc)
         TCGv_i32 treg = tcg_const_i32(dc->rd);
         TCGv_i32 tsize = tcg_const_i32(size - 1);
 
-        tcg_gen_movi_i32(cpu_pc, dc->pc);
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
         gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
 
         tcg_temp_free_i32(t0);
@@ -1114,7 +1111,7 @@ static void dec_store(DisasContext *dc)
         TCGv_i32 treg = tcg_const_i32(dc->rd);
         TCGv_i32 tsize = tcg_const_i32(size - 1);
 
-        tcg_gen_movi_i32(cpu_pc, dc->pc);
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
         /* FIXME: if the alignment is wrong, we should restore the value
          *        in memory. One possible way to achieve this is to probe
          *        the MMU prior to the memaccess, thay way we could put
@@ -1201,12 +1198,12 @@ static void dec_bcc(DisasContext *dc)
     if (dec_alu_op_b_is_small_imm(dc)) {
         int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
 
-        tcg_gen_movi_i32(cpu_btarget, dc->pc + offset);
+        tcg_gen_movi_i32(cpu_btarget, dc->base.pc_next + offset);
         dc->jmp = JMP_DIRECT_CC;
-        dc->jmp_pc = dc->pc + offset;
+        dc->jmp_pc = dc->base.pc_next + offset;
     } else {
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
+        tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->base.pc_next);
     }
     eval_cc(dc, cc, cpu_btaken, cpu_R[dc->ra]);
 }
@@ -1250,7 +1247,7 @@ static void dec_br(DisasContext *dc)
                            +offsetof(CPUState, halted));
             tcg_temp_free_i32(tmp_1);
 
-            tcg_gen_movi_i32(cpu_pc, dc->pc + 4);
+            tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
 
             gen_raise_exception(dc, EXCP_HLT);
             return;
@@ -1270,7 +1267,7 @@ static void dec_br(DisasContext *dc)
         dec_setup_dslot(dc);
     }
     if (link && dc->rd)
-        tcg_gen_movi_i32(cpu_R[dc->rd], dc->pc);
+        tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
 
     dc->jmp = JMP_INDIRECT;
     if (abs) {
@@ -1291,10 +1288,10 @@ static void dec_br(DisasContext *dc)
     } else {
         if (dec_alu_op_b_is_small_imm(dc)) {
             dc->jmp = JMP_DIRECT;
-            dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
+            dc->jmp_pc = dc->base.pc_next + (int32_t)((int16_t)dc->imm);
         } else {
             tcg_gen_movi_i32(cpu_btaken, 1);
-            tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
+            tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->base.pc_next);
         }
     }
 }
@@ -1459,7 +1456,8 @@ static void dec_fpu(DisasContext *dc)
                     qemu_log_mask(LOG_UNIMP,
                                   "unimplemented fcmp fpu_insn=%x pc=%x"
                                   " opc=%x\n",
-                                  fpu_insn, dc->pc, dc->opcode);
+                                  fpu_insn, (uint32_t)dc->base.pc_next,
+                                  dc->opcode);
                     dc->abort_at_next_insn = 1;
                     break;
             }
@@ -1489,7 +1487,7 @@ static void dec_fpu(DisasContext *dc)
         default:
             qemu_log_mask(LOG_UNIMP, "unimplemented FPU insn fpu_insn=%x pc=%x"
                           " opc=%x\n",
-                          fpu_insn, dc->pc, dc->opcode);
+                          fpu_insn, (uint32_t)dc->base.pc_next, dc->opcode);
             dc->abort_at_next_insn = 1;
             break;
     }
@@ -1500,7 +1498,8 @@ static void dec_null(DisasContext *dc)
     if (trap_illegal(dc, true)) {
         return;
     }
-    qemu_log_mask(LOG_GUEST_ERROR, "unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
+    qemu_log_mask(LOG_GUEST_ERROR, "unknown insn pc=%x opc=%x\n",
+                  (uint32_t)dc->base.pc_next, dc->opcode);
     dc->abort_at_next_insn = 1;
 }
 
@@ -1610,19 +1609,20 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
 
     pc_start = tb->pc;
     dc->cpu = cpu;
-    dc->tb = tb;
     org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
 
-    dc->is_jmp = DISAS_NEXT;
     dc->jmp = 0;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
     if (dc->delayed_branch) {
         dc->jmp = JMP_INDIRECT;
     }
-    dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->base.pc_first = pc_start;
+    dc->base.pc_next = pc_start;
+    dc->base.singlestep_enabled = cs->singlestep_enabled;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
+    dc->base.is_jmp = DISAS_NEXT;
+    dc->base.tb = tb;
 
     if (pc_start & 3) {
         cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
@@ -1634,31 +1634,31 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     gen_tb_start(tb);
     do
     {
-        tcg_gen_insn_start(dc->pc);
+        tcg_gen_insn_start(dc->base.pc_next);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cs, dc->base.pc_next, BP_ANY))) {
             gen_raise_exception_sync(dc, EXCP_DEBUG);
             /* 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 += 4;
+            dc->base.pc_next += 4;
             break;
         }
 
         /* Pretty disas.  */
-        LOG_DIS("%8.8x:\t", dc->pc);
+        LOG_DIS("%8.8x:\t", (uint32_t)dc->base.pc_next);
 
         if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
             gen_io_start();
         }
 
         dc->clear_imm = 1;
-        decode(dc, cpu_ldl_code(env, dc->pc));
+        decode(dc, cpu_ldl_code(env, dc->base.pc_next));
         if (dc->clear_imm)
             dc->tb_flags &= ~IMM_FLAG;
-        dc->pc += 4;
+        dc->base.pc_next += 4;
 
         if (dc->delayed_branch) {
             dc->delayed_branch--;
@@ -1673,10 +1673,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                 dc->tb_flags &= ~D_FLAG;
                 /* If it is a direct jump, try direct chaining.  */
                 if (dc->jmp == JMP_INDIRECT) {
-                    TCGv_i32 tmp_pc = tcg_const_i32(dc->pc);
+                    TCGv_i32 tmp_pc = tcg_const_i32(dc->base.pc_next);
                     eval_cond_jmp(dc, cpu_btarget, tmp_pc);
                     tcg_temp_free_i32(tmp_pc);
-                    dc->is_jmp = DISAS_JUMP;
+                    dc->base.is_jmp = DISAS_JUMP;
                 } else if (dc->jmp == JMP_DIRECT) {
                     t_sync_flags(dc);
                     gen_goto_tb(dc, 0, dc->jmp_pc);
@@ -1685,26 +1685,26 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                     t_sync_flags(dc);
                     /* Conditional jmp.  */
                     tcg_gen_brcondi_i32(TCG_COND_NE, cpu_btaken, 0, l1);
-                    gen_goto_tb(dc, 1, dc->pc);
+                    gen_goto_tb(dc, 1, dc->base.pc_next);
                     gen_set_label(l1);
                     gen_goto_tb(dc, 0, dc->jmp_pc);
                 }
                 break;
             }
         }
-        if (cs->singlestep_enabled) {
+        if (dc->base.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)
+             && (dc->base.pc_next - page_start < TARGET_PAGE_SIZE)
              && num_insns < max_insns);
 
-    npc = dc->pc;
+    npc = dc->base.pc_next;
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
         if (dc->tb_flags & D_FLAG) {
-            dc->is_jmp = DISAS_UPDATE;
+            dc->base.is_jmp = DISAS_UPDATE;
             tcg_gen_movi_i32(cpu_pc, npc);
             sync_jmpstate(dc);
         } else
@@ -1712,25 +1712,25 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     }
 
     /* 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 || org_flags != dc->tb_flags)) {
-        dc->is_jmp = DISAS_UPDATE;
+        dc->base.is_jmp = DISAS_UPDATE;
         tcg_gen_movi_i32(cpu_pc, npc);
     }
     t_sync_flags(dc);
 
-    if (dc->is_jmp == DISAS_NORETURN) {
+    if (dc->base.is_jmp == DISAS_NORETURN) {
         /* nothing more to generate */
     } else if (unlikely(cs->singlestep_enabled)) {
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
-        if (dc->is_jmp != DISAS_JUMP) {
+        if (dc->base.is_jmp != DISAS_JUMP) {
             tcg_gen_movi_i32(cpu_pc, npc);
         }
         gen_helper_raise_exception(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
     } else {
-        switch(dc->is_jmp) {
+        switch (dc->base.is_jmp) {
             case DISAS_NEXT:
                 gen_goto_tb(dc, 1, npc);
                 break;
@@ -1746,7 +1746,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
     }
     gen_tb_end(tb, num_insns);
 
-    tb->size = dc->pc - pc_start;
+    tb->size = dc->base.pc_next - pc_start;
     tb->icount = num_insns;
 
 #ifdef DEBUG_DISAS
@@ -1755,7 +1755,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
         && qemu_log_in_addr_range(pc_start)) {
         FILE *logfile = qemu_log_lock();
         qemu_log("--------------\n");
-        log_target_disas(cs, pc_start, dc->pc - pc_start);
+        log_target_disas(cs, pc_start, dc->base.pc_next - pc_start);
         qemu_log_unlock(logfile);
     }
 #endif
-- 
2.25.1



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

* [PATCH v2 29/76] target/microblaze: Convert to translator_loop
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (27 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 28/76] target/microblaze: Convert to DisasContextBase Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 30/76] target/microblaze: Remove SIM_COMPAT Richard Henderson
                   ` (47 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Part two of conversion to the generic translator_loop.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/translate.c | 289 ++++++++++++++++++----------------
 1 file changed, 149 insertions(+), 140 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 45b1555f85..6a9710d76d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1595,172 +1595,181 @@ static inline void decode(DisasContext *dc, uint32_t ir)
     }
 }
 
-/* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
 {
-    CPUMBState *env = cs->env_ptr;
-    MicroBlazeCPU *cpu = env_archcpu(env);
-    uint32_t pc_start;
-    struct DisasContext ctx;
-    struct DisasContext *dc = &ctx;
-    uint32_t page_start, org_flags;
-    uint32_t npc;
-    int num_insns;
+    DisasContext *dc = container_of(dcb, DisasContext, base);
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    int bound;
 
-    pc_start = tb->pc;
     dc->cpu = cpu;
-    org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
-
-    dc->jmp = 0;
+    dc->synced_flags = dc->tb_flags = dc->base.tb->flags;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
-    if (dc->delayed_branch) {
-        dc->jmp = JMP_INDIRECT;
-    }
-    dc->base.pc_first = pc_start;
-    dc->base.pc_next = pc_start;
-    dc->base.singlestep_enabled = cs->singlestep_enabled;
+    dc->jmp = dc->delayed_branch ? JMP_INDIRECT : JMP_NOJMP;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
-    dc->base.is_jmp = DISAS_NEXT;
-    dc->base.tb = tb;
 
-    if (pc_start & 3) {
-        cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
+    bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
+    dc->base.max_insns = MIN(dc->base.max_insns, bound);
+}
+
+static void mb_tr_tb_start(DisasContextBase *dcb, CPUState *cs)
+{
+}
+
+static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
+{
+    tcg_gen_insn_start(dcb->pc_next);
+}
+
+static bool mb_tr_breakpoint_check(DisasContextBase *dcb, CPUState *cs,
+                                   const CPUBreakpoint *bp)
+{
+    DisasContext *dc = container_of(dcb, DisasContext, base);
+
+    gen_raise_exception_sync(dc, EXCP_DEBUG);
+
+    /*
+     * 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->base.pc_next += 4;
+    return true;
+}
+
+static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
+{
+    DisasContext *dc = container_of(dcb, DisasContext, base);
+    CPUMBState *env = cs->env_ptr;
+
+    /* TODO: This should raise an exception, not terminate qemu. */
+    if (dc->base.pc_next & 3) {
+        cpu_abort(cs, "Microblaze: unaligned PC=%x\n",
+                  (uint32_t)dc->base.pc_next);
     }
 
-    page_start = pc_start & TARGET_PAGE_MASK;
-    num_insns = 0;
+    dc->clear_imm = 1;
+    decode(dc, cpu_ldl_code(env, dc->base.pc_next));
+    if (dc->clear_imm) {
+        dc->tb_flags &= ~IMM_FLAG;
+    }
+    dc->base.pc_next += 4;
 
-    gen_tb_start(tb);
-    do
-    {
-        tcg_gen_insn_start(dc->base.pc_next);
-        num_insns++;
-
-        if (unlikely(cpu_breakpoint_test(cs, dc->base.pc_next, BP_ANY))) {
-            gen_raise_exception_sync(dc, EXCP_DEBUG);
-            /* 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->base.pc_next += 4;
-            break;
+    if (dc->delayed_branch && --dc->delayed_branch == 0) {
+        if (dc->tb_flags & DRTI_FLAG) {
+            do_rti(dc);
         }
-
-        /* Pretty disas.  */
-        LOG_DIS("%8.8x:\t", (uint32_t)dc->base.pc_next);
-
-        if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
-            gen_io_start();
+        if (dc->tb_flags & DRTB_FLAG) {
+            do_rtb(dc);
         }
-
-        dc->clear_imm = 1;
-        decode(dc, cpu_ldl_code(env, dc->base.pc_next));
-        if (dc->clear_imm)
-            dc->tb_flags &= ~IMM_FLAG;
-        dc->base.pc_next += 4;
-
-        if (dc->delayed_branch) {
-            dc->delayed_branch--;
-            if (!dc->delayed_branch) {
-                if (dc->tb_flags & DRTI_FLAG)
-                    do_rti(dc);
-                 if (dc->tb_flags & DRTB_FLAG)
-                    do_rtb(dc);
-                if (dc->tb_flags & DRTE_FLAG)
-                    do_rte(dc);
-                /* Clear the delay slot flag.  */
-                dc->tb_flags &= ~D_FLAG;
-                /* If it is a direct jump, try direct chaining.  */
-                if (dc->jmp == JMP_INDIRECT) {
-                    TCGv_i32 tmp_pc = tcg_const_i32(dc->base.pc_next);
-                    eval_cond_jmp(dc, cpu_btarget, tmp_pc);
-                    tcg_temp_free_i32(tmp_pc);
-                    dc->base.is_jmp = DISAS_JUMP;
-                } else if (dc->jmp == JMP_DIRECT) {
-                    t_sync_flags(dc);
-                    gen_goto_tb(dc, 0, dc->jmp_pc);
-                } else if (dc->jmp == JMP_DIRECT_CC) {
-                    TCGLabel *l1 = gen_new_label();
-                    t_sync_flags(dc);
-                    /* Conditional jmp.  */
-                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_btaken, 0, l1);
-                    gen_goto_tb(dc, 1, dc->base.pc_next);
-                    gen_set_label(l1);
-                    gen_goto_tb(dc, 0, dc->jmp_pc);
-                }
-                break;
-            }
+        if (dc->tb_flags & DRTE_FLAG) {
+            do_rte(dc);
         }
-        if (dc->base.singlestep_enabled) {
-            break;
-        }
-    } while (!dc->base.is_jmp && !dc->cpustate_changed
-             && !tcg_op_buf_full()
-             && !singlestep
-             && (dc->base.pc_next - page_start < TARGET_PAGE_SIZE)
-             && num_insns < max_insns);
-
-    npc = dc->base.pc_next;
-    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
-        if (dc->tb_flags & D_FLAG) {
-            dc->base.is_jmp = DISAS_UPDATE;
-            tcg_gen_movi_i32(cpu_pc, npc);
-            sync_jmpstate(dc);
-        } else
-            npc = dc->jmp_pc;
+        /* Clear the delay slot flag.  */
+        dc->tb_flags &= ~D_FLAG;
+        dc->base.is_jmp = DISAS_JUMP;
     }
 
-    /* Force an update if the per-tb cpu state has changed.  */
-    if (dc->base.is_jmp == DISAS_NEXT
-        && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
+    /* Force an exit 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_i32(cpu_pc, npc);
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
     }
-    t_sync_flags(dc);
+}
+
+static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
+{
+    DisasContext *dc = container_of(dcb, DisasContext, base);
+
+    assert(!dc->abort_at_next_insn);
 
     if (dc->base.is_jmp == DISAS_NORETURN) {
-        /* nothing more to generate */
-    } else if (unlikely(cs->singlestep_enabled)) {
-        TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
-
-        if (dc->base.is_jmp != DISAS_JUMP) {
-            tcg_gen_movi_i32(cpu_pc, npc);
-        }
-        gen_helper_raise_exception(cpu_env, tmp);
-        tcg_temp_free_i32(tmp);
-    } else {
-        switch (dc->base.is_jmp) {
-            case DISAS_NEXT:
-                gen_goto_tb(dc, 1, npc);
-                break;
-            case DISAS_JUMP:
-            case DISAS_UPDATE:
-                /* indicate that the hash table must be used
-                   to find the next TB */
-                tcg_gen_exit_tb(NULL, 0);
-                break;
-            default:
-                g_assert_not_reached();
-        }
+        /* We have already exited the TB. */
+        return;
     }
-    gen_tb_end(tb, num_insns);
 
-    tb->size = dc->base.pc_next - pc_start;
-    tb->icount = num_insns;
+    t_sync_flags(dc);
+    if (dc->tb_flags & D_FLAG) {
+        sync_jmpstate(dc);
+        dc->jmp = JMP_NOJMP;
+    }
 
+    switch (dc->base.is_jmp) {
+    case DISAS_TOO_MANY:
+        assert(dc->jmp == JMP_NOJMP);
+        gen_goto_tb(dc, 0, dc->base.pc_next);
+        return;
+
+    case DISAS_UPDATE:
+        assert(dc->jmp == JMP_NOJMP);
+        if (unlikely(cs->singlestep_enabled)) {
+            gen_raise_exception(dc, EXCP_DEBUG);
+        } else {
+            tcg_gen_exit_tb(NULL, 0);
+        }
+        return;
+
+    case DISAS_JUMP:
+        switch (dc->jmp) {
+        case JMP_INDIRECT:
+            {
+                TCGv_i32 tmp_pc = tcg_const_i32(dc->base.pc_next);
+                eval_cond_jmp(dc, cpu_btarget, tmp_pc);
+                tcg_temp_free_i32(tmp_pc);
+
+                if (unlikely(cs->singlestep_enabled)) {
+                    gen_raise_exception(dc, EXCP_DEBUG);
+                } else {
+                    tcg_gen_exit_tb(NULL, 0);
+                }
+            }
+            return;
+
+        case JMP_DIRECT_CC:
+            {
+                TCGLabel *l1 = gen_new_label();
+                tcg_gen_brcondi_i32(TCG_COND_NE, cpu_btaken, 0, l1);
+                gen_goto_tb(dc, 1, dc->base.pc_next);
+                gen_set_label(l1);
+            }
+            /* fall through */
+
+        case JMP_DIRECT:
+            gen_goto_tb(dc, 0, dc->jmp_pc);
+            return;
+        }
+        /* fall through */
+
+    default:
+        g_assert_not_reached();
+    }
+}
+
+static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)
+{
 #ifdef DEBUG_DISAS
 #if !SIM_COMPAT
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(pc_start)) {
-        FILE *logfile = qemu_log_lock();
-        qemu_log("--------------\n");
-        log_target_disas(cs, pc_start, dc->base.pc_next - pc_start);
-        qemu_log_unlock(logfile);
-    }
+    qemu_log("IN: %s\n", lookup_symbol(dcb->pc_first));
+    log_target_disas(cs, dcb->pc_first, dcb->tb->size);
 #endif
 #endif
-    assert(!dc->abort_at_next_insn);
+}
+
+static const TranslatorOps mb_tr_ops = {
+    .init_disas_context = mb_tr_init_disas_context,
+    .tb_start           = mb_tr_tb_start,
+    .insn_start         = mb_tr_insn_start,
+    .breakpoint_check   = mb_tr_breakpoint_check,
+    .translate_insn     = mb_tr_translate_insn,
+    .tb_stop            = mb_tr_tb_stop,
+    .disas_log          = mb_tr_disas_log,
+};
+
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
+{
+    DisasContext dc;
+    translator_loop(&mb_tr_ops, &dc.base, cpu, tb, max_insns);
 }
 
 void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-- 
2.25.1



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

* [PATCH v2 30/76] target/microblaze: Remove SIM_COMPAT
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (28 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 29/76] target/microblaze: Convert to translator_loop Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 31/76] target/microblaze: Remove DISAS_GNU Richard Henderson
                   ` (46 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 6a9710d76d..a90e56a17f 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -34,10 +34,9 @@
 #include "exec/log.h"
 
 
-#define SIM_COMPAT 0
 #define DISAS_GNU 1
 #define DISAS_MB 1
-#if DISAS_MB && !SIM_COMPAT
+#if DISAS_MB
 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
 #else
 #  define LOG_DIS(...) do { } while (0)
@@ -1749,11 +1748,9 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
 static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)
 {
 #ifdef DEBUG_DISAS
-#if !SIM_COMPAT
     qemu_log("IN: %s\n", lookup_symbol(dcb->pc_first));
     log_target_disas(cs, dcb->pc_first, dcb->tb->size);
 #endif
-#endif
 }
 
 static const TranslatorOps mb_tr_ops = {
-- 
2.25.1



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

* [PATCH v2 31/76] target/microblaze: Remove DISAS_GNU
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (29 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 30/76] target/microblaze: Remove SIM_COMPAT Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 32/76] target/microblaze: Remove empty D macros Richard Henderson
                   ` (45 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This is never used.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a90e56a17f..6757720776 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -34,7 +34,6 @@
 #include "exec/log.h"
 
 
-#define DISAS_GNU 1
 #define DISAS_MB 1
 #if DISAS_MB
 #  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
-- 
2.25.1



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

* [PATCH v2 32/76] target/microblaze: Remove empty D macros
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (30 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 31/76] target/microblaze: Remove DISAS_GNU Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-31 21:14   ` Philippe Mathieu-Daudé
  2020-08-28 14:18 ` [PATCH v2 33/76] target/microblaze: Remove LOG_DIS Richard Henderson
                   ` (44 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This is never used in op_helper.c and translate.c.  There are
two trivial uses in helper.c which can be improved by always
logging MMU_EXCP to CPU_LOG_INT.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.c    | 11 ++++-------
 target/microblaze/op_helper.c |  2 --
 target/microblaze/translate.c |  2 --
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 9a95456401..f8e2ca12a9 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -24,8 +24,6 @@
 #include "qemu/host-utils.h"
 #include "exec/log.h"
 
-#define D(x)
-
 #if defined(CONFIG_USER_ONLY)
 
 void mb_cpu_do_interrupt(CPUState *cs)
@@ -155,10 +153,13 @@ void mb_cpu_do_interrupt(CPUState *cs)
         case EXCP_MMU:
             env->regs[17] = env->pc;
 
+            qemu_log_mask(CPU_LOG_INT,
+                          "MMU exception at pc=%x iflags=%x ear=%" PRIx64 "\n",
+                          env->pc, env->iflags, env->ear);
+
             env->esr &= ~(1 << 12);
             /* Exception breaks branch + dslot sequence?  */
             if (env->iflags & D_FLAG) {
-                D(qemu_log("D_FLAG set at exception bimm=%d\n", env->bimm));
                 env->esr |= 1 << 12 ;
                 env->btr = env->btarget;
 
@@ -166,14 +167,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
                 env->regs[17] -= 4;
                 /* was the branch immprefixed?.  */
                 if (env->bimm) {
-                    qemu_log_mask(CPU_LOG_INT,
-                                  "bimm exception at pc=%x iflags=%x\n",
-                                  env->pc, env->iflags);
                     env->regs[17] -= 4;
                     log_cpu_state_mask(CPU_LOG_INT, cs, 0);
                 }
             } else if (env->iflags & IMM_FLAG) {
-                D(qemu_log("IMM_FLAG set at exception\n"));
                 env->regs[17] -= 4;
             }
 
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index d79202c3f8..decdca0fd8 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -26,8 +26,6 @@
 #include "exec/cpu_ldst.h"
 #include "fpu/softfloat.h"
 
-#define D(x)
-
 void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
 {
     int test = ctrl & STREAM_TEST;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 6757720776..860859324a 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -41,8 +41,6 @@
 #  define LOG_DIS(...) do { } while (0)
 #endif
 
-#define D(x)
-
 #define EXTRACT_FIELD(src, start, end) \
             (((src) >> start) & ((1 << (end - start + 1)) - 1))
 
-- 
2.25.1



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

* [PATCH v2 33/76] target/microblaze: Remove LOG_DIS
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (31 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 32/76] target/microblaze: Remove empty D macros Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 34/76] target/microblaze: Ensure imm constant is always available Richard Henderson
                   ` (43 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Also remove the related defines, DISAS_MB and DEBUG_DISAS.
Rely on print_insn_microblaze.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/translate.c | 78 +----------------------------------
 1 file changed, 1 insertion(+), 77 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 860859324a..133ec24870 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -33,14 +33,6 @@
 #include "trace-tcg.h"
 #include "exec/log.h"
 
-
-#define DISAS_MB 1
-#if DISAS_MB
-#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
-#else
-#  define LOG_DIS(...) do { } while (0)
-#endif
-
 #define EXTRACT_FIELD(src, start, end) \
             (((src) >> start) & ((1 << (end - start + 1)) - 1))
 
@@ -205,10 +197,6 @@ static void dec_add(DisasContext *dc)
     k = dc->opcode & 4;
     c = dc->opcode & 2;
 
-    LOG_DIS("add%s%s%s r%d r%d r%d\n",
-            dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
-            dc->rd, dc->ra, dc->rb);
-
     /* Take care of the easy cases first.  */
     if (k) {
         /* k - keep carry, no need to update MSR.  */
@@ -252,7 +240,6 @@ static void dec_sub(DisasContext *dc)
     cmp = (dc->imm & 1) && (!dc->type_b) && k;
 
     if (cmp) {
-        LOG_DIS("cmp%s r%d, r%d ir=%x\n", u ? "u" : "", dc->rd, dc->ra, dc->ir);
         if (dc->rd) {
             if (u)
                 gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
@@ -262,9 +249,6 @@ static void dec_sub(DisasContext *dc)
         return;
     }
 
-    LOG_DIS("sub%s%s r%d, r%d r%d\n",
-             k ? "k" : "",  c ? "c" : "", dc->rd, dc->ra, dc->rb);
-
     /* Take care of the easy cases first.  */
     if (k) {
         /* k - keep carry, no need to update MSR.  */
@@ -314,19 +298,16 @@ static void dec_pattern(DisasContext *dc)
     switch (mode) {
         case 0:
             /* pcmpbf.  */
-            LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             if (dc->rd)
                 gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
             break;
         case 2:
-            LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             if (dc->rd) {
                 tcg_gen_setcond_i32(TCG_COND_EQ, cpu_R[dc->rd],
                                    cpu_R[dc->ra], cpu_R[dc->rb]);
             }
             break;
         case 3:
-            LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             if (dc->rd) {
                 tcg_gen_setcond_i32(TCG_COND_NE, cpu_R[dc->rd],
                                    cpu_R[dc->ra], cpu_R[dc->rb]);
@@ -349,7 +330,6 @@ static void dec_and(DisasContext *dc)
     }
 
     not = dc->opcode & (1 << 1);
-    LOG_DIS("and%s\n", not ? "n" : "");
 
     if (!dc->rd)
         return;
@@ -367,7 +347,6 @@ static void dec_or(DisasContext *dc)
         return;
     }
 
-    LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
     if (dc->rd)
         tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
@@ -379,7 +358,6 @@ static void dec_xor(DisasContext *dc)
         return;
     }
 
-    LOG_DIS("xor r%d\n", dc->rd);
     if (dc->rd)
         tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
@@ -433,9 +411,6 @@ static void dec_msr(DisasContext *dc)
     if (clrset) {
         bool clr = extract32(dc->ir, 16, 1);
 
-        LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
-                dc->rd, dc->imm);
-
         if (!dc->cpu->cfg.use_msr_instr) {
             /* nop??? */
             return;
@@ -478,7 +453,6 @@ static void dec_msr(DisasContext *dc)
 
         sr &= 7;
         tmp_sr = tcg_const_i32(sr);
-        LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
         if (to) {
             gen_helper_mmu_write(cpu_env, tmp_ext, tmp_sr, cpu_R[dc->ra]);
         } else {
@@ -491,7 +465,6 @@ static void dec_msr(DisasContext *dc)
 #endif
 
     if (to) {
-        LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
         switch (sr) {
             case SR_PC:
                 break;
@@ -535,8 +508,6 @@ static void dec_msr(DisasContext *dc)
                 break;
         }
     } else {
-        LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm);
-
         switch (sr) {
             case SR_PC:
                 tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
@@ -609,7 +580,6 @@ static void dec_mul(DisasContext *dc)
     subcode = dc->imm & 3;
 
     if (dc->type_b) {
-        LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
         tcg_gen_mul_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
         return;
     }
@@ -622,21 +592,17 @@ static void dec_mul(DisasContext *dc)
     tmp = tcg_temp_new_i32();
     switch (subcode) {
         case 0:
-            LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             tcg_gen_mul_i32(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
             break;
         case 1:
-            LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             tcg_gen_muls2_i32(tmp, cpu_R[dc->rd],
                               cpu_R[dc->ra], cpu_R[dc->rb]);
             break;
         case 2:
-            LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             tcg_gen_mulsu2_i32(tmp, cpu_R[dc->rd],
                                cpu_R[dc->ra], cpu_R[dc->rb]);
             break;
         case 3:
-            LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
             tcg_gen_mulu2_i32(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
             break;
         default:
@@ -652,7 +618,6 @@ static void dec_div(DisasContext *dc)
     unsigned int u;
 
     u = dc->imm & 2; 
-    LOG_DIS("div\n");
 
     if (trap_illegal(dc, !dc->cpu->cfg.use_div)) {
         return;
@@ -688,10 +653,6 @@ static void dec_barrel(DisasContext *dc)
     imm_w = extract32(dc->imm, 6, 5);
     imm_s = extract32(dc->imm, 0, 5);
 
-    LOG_DIS("bs%s%s%s r%d r%d r%d\n",
-            e ? "e" : "",
-            s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);
-
     if (e) {
         if (imm_w + imm_s > 32 || imm_w == 0) {
             /* These inputs have an undefined behavior.  */
@@ -742,7 +703,6 @@ static void dec_bit(DisasContext *dc)
             /* src.  */
             t0 = tcg_temp_new_i32();
 
-            LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
             tcg_gen_shli_i32(t0, cpu_msr_c, 31);
             tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1);
             if (dc->rd) {
@@ -755,8 +715,6 @@ static void dec_bit(DisasContext *dc)
         case 0x1:
         case 0x41:
             /* srl.  */
-            LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);
-
             tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1);
             if (dc->rd) {
                 if (op == 0x41)
@@ -766,11 +724,9 @@ static void dec_bit(DisasContext *dc)
             }
             break;
         case 0x60:
-            LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
             tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
             break;
         case 0x61:
-            LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
             tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
             break;
         case 0x64:
@@ -778,12 +734,10 @@ static void dec_bit(DisasContext *dc)
         case 0x74:
         case 0x76:
             /* wdc.  */
-            LOG_DIS("wdc r%d\n", dc->ra);
             trap_userspace(dc, true);
             break;
         case 0x68:
             /* wic.  */
-            LOG_DIS("wic r%d\n", dc->ra);
             trap_userspace(dc, true);
             break;
         case 0xe0:
@@ -796,12 +750,10 @@ static void dec_bit(DisasContext *dc)
             break;
         case 0x1e0:
             /* swapb */
-            LOG_DIS("swapb r%d r%d\n", dc->rd, dc->ra);
             tcg_gen_bswap32_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
             break;
         case 0x1e2:
             /*swaph */
-            LOG_DIS("swaph r%d r%d\n", dc->rd, dc->ra);
             tcg_gen_rotri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 16);
             break;
         default:
@@ -824,7 +776,6 @@ static inline void sync_jmpstate(DisasContext *dc)
 
 static void dec_imm(DisasContext *dc)
 {
-    LOG_DIS("imm %x\n", dc->imm << 16);
     tcg_gen_movi_i32(cpu_imm, (dc->imm << 16));
     dc->tb_flags |= IMM_FLAG;
     dc->clear_imm = 0;
@@ -928,10 +879,6 @@ static void dec_load(DisasContext *dc)
         return;
     }
 
-    LOG_DIS("l%d%s%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
-                                                        ex ? "x" : "",
-                                                        ea ? "ea" : "");
-
     t_sync_flags(dc);
     addr = tcg_temp_new();
     compute_ldst_addr(dc, ea, addr);
@@ -1039,9 +986,6 @@ static void dec_store(DisasContext *dc)
 
     trap_userspace(dc, ea);
 
-    LOG_DIS("s%d%s%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
-                                                        ex ? "x" : "",
-                                                        ea ? "ea" : "");
     t_sync_flags(dc);
     /* If we get a fault on a dslot, the jmpstate better be in sync.  */
     sync_jmpstate(dc);
@@ -1184,7 +1128,6 @@ static void dec_bcc(DisasContext *dc)
 
     cc = EXTRACT_FIELD(dc->ir, 21, 23);
     dslot = dc->ir & (1 << 25);
-    LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm);
 
     dc->delayed_branch = 1;
     if (dslot) {
@@ -1217,8 +1160,6 @@ static void dec_br(DisasContext *dc)
     if (mbar == 2 && dc->imm == 4) {
         uint16_t mbar_imm = dc->rd;
 
-        LOG_DIS("mbar %d\n", mbar_imm);
-
         /* Data access memory barrier.  */
         if ((mbar_imm & 2) == 0) {
             tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
@@ -1228,8 +1169,6 @@ static void dec_br(DisasContext *dc)
         if (mbar_imm & 16) {
             TCGv_i32 tmp_1;
 
-            LOG_DIS("sleep\n");
-
             if (trap_userspace(dc, true)) {
                 /* Sleep is a privileged instruction.  */
                 return;
@@ -1253,11 +1192,6 @@ static void dec_br(DisasContext *dc)
         return;
     }
 
-    LOG_DIS("br%s%s%s%s imm=%x\n",
-             abs ? "a" : "", link ? "l" : "",
-             dc->type_b ? "i" : "", dslot ? "d" : "",
-             dc->imm);
-
     dc->delayed_branch = 1;
     if (dslot) {
         dec_setup_dslot(dc);
@@ -1363,16 +1297,12 @@ static void dec_rts(DisasContext *dc)
     dec_setup_dslot(dc);
 
     if (i_bit) {
-        LOG_DIS("rtid ir=%x\n", dc->ir);
         dc->tb_flags |= DRTI_FLAG;
     } else if (b_bit) {
-        LOG_DIS("rtbd ir=%x\n", dc->ir);
         dc->tb_flags |= DRTB_FLAG;
     } else if (e_bit) {
-        LOG_DIS("rted ir=%x\n", dc->ir);
         dc->tb_flags |= DRTE_FLAG;
-    } else
-        LOG_DIS("rts ir=%x\n", dc->ir);
+    }
 
     dc->jmp = JMP_INDIRECT;
     tcg_gen_movi_i32(cpu_btaken, 1);
@@ -1505,9 +1435,6 @@ static void dec_stream(DisasContext *dc)
     TCGv_i32 t_id, t_ctrl;
     int ctrl;
 
-    LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put",
-            dc->type_b ? "" : "d", dc->imm);
-
     if (trap_userspace(dc, true)) {
         return;
     }
@@ -1565,7 +1492,6 @@ static inline void decode(DisasContext *dc, uint32_t ir)
     int i;
 
     dc->ir = ir;
-    LOG_DIS("%8.8x\t", dc->ir);
 
     if (ir == 0) {
         trap_illegal(dc, dc->cpu->cfg.opcode_0_illegal);
@@ -1744,10 +1670,8 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
 
 static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)
 {
-#ifdef DEBUG_DISAS
     qemu_log("IN: %s\n", lookup_symbol(dcb->pc_first));
     log_target_disas(cs, dcb->pc_first, dcb->tb->size);
-#endif
 }
 
 static const TranslatorOps mb_tr_ops = {
-- 
2.25.1



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

* [PATCH v2 34/76] target/microblaze: Ensure imm constant is always available
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (32 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 33/76] target/microblaze: Remove LOG_DIS Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 35/76] target/microblaze: Add decodetree infrastructure Richard Henderson
                   ` (42 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Include the env->imm value in the TB values when IMM_FLAG is set.
This means that we can always reconstruct the complete 32-bit imm.
Discard env_imm when its contents can no longer be accessed.

Fix user-mode checks for BRK/BRKI, which depend on IMM.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |   2 +-
 target/microblaze/translate.c | 111 ++++++++++++++++++++--------------
 2 files changed, 67 insertions(+), 46 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 7066878ac7..013858b8e0 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -374,9 +374,9 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
     *pc = env->pc;
-    *cs_base = 0;
     *flags = (env->iflags & IFLAGS_TB_MASK) |
              (env->msr & (MSR_UM | MSR_VM | MSR_EE));
+    *cs_base = (*flags & IMM_FLAG ? env->imm : 0);
 }
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 133ec24870..65ce8f3cd6 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -61,6 +61,7 @@ typedef struct DisasContext {
     /* Decoder.  */
     int type_b;
     uint32_t ir;
+    uint32_t ext_imm;
     uint8_t opcode;
     uint8_t rd, ra, rb;
     uint16_t imm;
@@ -169,24 +170,23 @@ static bool trap_userspace(DisasContext *dc, bool cond)
     return cond_user;
 }
 
-/* True if ALU operand b is a small immediate that may deserve
-   faster treatment.  */
-static inline int dec_alu_op_b_is_small_imm(DisasContext *dc)
+static int32_t dec_alu_typeb_imm(DisasContext *dc)
 {
-    /* Immediate insn without the imm prefix ?  */
-    return dc->type_b && !(dc->tb_flags & IMM_FLAG);
+    tcg_debug_assert(dc->type_b);
+    if (dc->tb_flags & IMM_FLAG) {
+        return dc->ext_imm | dc->imm;
+    } else {
+        return (int16_t)dc->imm;
+    }
 }
 
 static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
 {
     if (dc->type_b) {
-        if (dc->tb_flags & IMM_FLAG)
-            tcg_gen_ori_i32(cpu_imm, cpu_imm, dc->imm);
-        else
-            tcg_gen_movi_i32(cpu_imm, (int32_t)((int16_t)dc->imm));
+        tcg_gen_movi_i32(cpu_imm, dec_alu_typeb_imm(dc));
         return &cpu_imm;
-    } else
-        return &cpu_R[dc->rb];
+    }
+    return &cpu_R[dc->rb];
 }
 
 static void dec_add(DisasContext *dc)
@@ -776,14 +776,14 @@ static inline void sync_jmpstate(DisasContext *dc)
 
 static void dec_imm(DisasContext *dc)
 {
-    tcg_gen_movi_i32(cpu_imm, (dc->imm << 16));
+    dc->ext_imm = dc->imm << 16;
+    tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
     dc->tb_flags |= IMM_FLAG;
     dc->clear_imm = 0;
 }
 
 static inline void compute_ldst_addr(DisasContext *dc, bool ea, TCGv t)
 {
-    bool extimm = dc->tb_flags & IMM_FLAG;
     /* Should be set to true if r1 is used by loadstores.  */
     bool stackprot = false;
     TCGv_i32 t32;
@@ -836,11 +836,7 @@ static inline void compute_ldst_addr(DisasContext *dc, bool ea, TCGv t)
     }
     /* Immediate.  */
     t32 = tcg_temp_new_i32();
-    if (!extimm) {
-        tcg_gen_addi_i32(t32, cpu_R[dc->ra], (int16_t)dc->imm);
-    } else {
-        tcg_gen_add_i32(t32, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-    }
+    tcg_gen_addi_i32(t32, cpu_R[dc->ra], dec_alu_typeb_imm(dc));
     tcg_gen_extu_i32_tl(t, t32);
     tcg_temp_free_i32(t32);
 
@@ -1134,15 +1130,13 @@ static void dec_bcc(DisasContext *dc)
         dec_setup_dslot(dc);
     }
 
-    if (dec_alu_op_b_is_small_imm(dc)) {
-        int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend.  */
-
-        tcg_gen_movi_i32(cpu_btarget, dc->base.pc_next + offset);
+    if (dc->type_b) {
         dc->jmp = JMP_DIRECT_CC;
-        dc->jmp_pc = dc->base.pc_next + offset;
+        dc->jmp_pc = dc->base.pc_next + dec_alu_typeb_imm(dc);
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
     } else {
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->base.pc_next);
+        tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], dc->base.pc_next);
     }
     eval_cc(dc, cc, cpu_btaken, cpu_R[dc->ra]);
 }
@@ -1192,38 +1186,63 @@ static void dec_br(DisasContext *dc)
         return;
     }
 
+    if (abs && link && !dslot) {
+        if (dc->type_b) {
+            /* BRKI */
+            uint32_t imm = dec_alu_typeb_imm(dc);
+            if (trap_userspace(dc, imm != 8 && imm != 0x18)) {
+                return;
+            }
+        } else {
+            /* BRK */
+            if (trap_userspace(dc, true)) {
+                return;
+            }
+        }
+    }
+
     dc->delayed_branch = 1;
     if (dslot) {
         dec_setup_dslot(dc);
     }
-    if (link && dc->rd)
+    if (link && dc->rd) {
         tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
+    }
 
-    dc->jmp = JMP_INDIRECT;
     if (abs) {
-        tcg_gen_movi_i32(cpu_btaken, 1);
-        tcg_gen_mov_i32(cpu_btarget, *(dec_alu_op_b(dc)));
-        if (link && !dslot) {
-            if (!(dc->tb_flags & IMM_FLAG) &&
-                (dc->imm == 8 || dc->imm == 0x18)) {
+        if (dc->type_b) {
+            uint32_t dest = dec_alu_typeb_imm(dc);
+
+            dc->jmp = JMP_DIRECT;
+            dc->jmp_pc = dest;
+            tcg_gen_movi_i32(cpu_btarget, dest);
+            if (link && !dslot) {
+                switch (dest) {
+                case 8:
+                case 0x18:
+                    gen_raise_exception_sync(dc, EXCP_BREAK);
+                    break;
+                case 0:
+                    gen_raise_exception_sync(dc, EXCP_DEBUG);
+                    break;
+                }
+            }
+        } else {
+            dc->jmp = JMP_INDIRECT;
+            tcg_gen_mov_i32(cpu_btarget, cpu_R[dc->rb]);
+            if (link && !dslot) {
                 gen_raise_exception_sync(dc, EXCP_BREAK);
             }
-            if (dc->imm == 0) {
-                if (trap_userspace(dc, true)) {
-                    return;
-                }
-                gen_raise_exception_sync(dc, EXCP_DEBUG);
-            }
         }
+    } else if (dc->type_b) {
+        dc->jmp = JMP_DIRECT;
+        dc->jmp_pc = dc->base.pc_next + dec_alu_typeb_imm(dc);
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
     } else {
-        if (dec_alu_op_b_is_small_imm(dc)) {
-            dc->jmp = JMP_DIRECT;
-            dc->jmp_pc = dc->base.pc_next + (int32_t)((int16_t)dc->imm);
-        } else {
-            tcg_gen_movi_i32(cpu_btaken, 1);
-            tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->base.pc_next);
-        }
+        dc->jmp = JMP_INDIRECT;
+        tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], dc->base.pc_next);
     }
+    tcg_gen_movi_i32(cpu_btaken, 1);
 }
 
 static inline void do_rti(DisasContext *dc)
@@ -1529,6 +1548,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->jmp = dc->delayed_branch ? JMP_INDIRECT : JMP_NOJMP;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
+    dc->ext_imm = dc->base.tb->cs_base;
 
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
     dc->base.max_insns = MIN(dc->base.max_insns, bound);
@@ -1573,8 +1593,9 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
 
     dc->clear_imm = 1;
     decode(dc, cpu_ldl_code(env, dc->base.pc_next));
-    if (dc->clear_imm) {
+    if (dc->clear_imm && (dc->tb_flags & IMM_FLAG)) {
         dc->tb_flags &= ~IMM_FLAG;
+        tcg_gen_discard_i32(cpu_imm);
     }
     dc->base.pc_next += 4;
 
-- 
2.25.1



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

* [PATCH v2 35/76] target/microblaze: Add decodetree infrastructure
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (33 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 34/76] target/microblaze: Ensure imm constant is always available Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 36/76] target/microblaze: Convert dec_add to decodetree Richard Henderson
                   ` (41 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The new interface is a stub that recognizes no instructions.
It falls back to the old decoder for all instructions.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode | 18 ++++++++++++++++++
 target/microblaze/translate.c  | 11 +++++++++--
 target/microblaze/meson.build  |  3 +++
 3 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 target/microblaze/insns.decode

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
new file mode 100644
index 0000000000..1ed9ca0731
--- /dev/null
+++ b/target/microblaze/insns.decode
@@ -0,0 +1,18 @@
+#
+# MicroBlaze instruction decode definitions.
+#
+# Copyright (c) 2020 Richard Henderson <rth@twiddle.net>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 65ce8f3cd6..e624093745 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -81,6 +81,9 @@ typedef struct DisasContext {
     int abort_at_next_insn;
 } DisasContext;
 
+/* Include the auto-generated decoder.  */
+#include "decode-insns.c.inc"
+
 static inline void t_sync_flags(DisasContext *dc)
 {
     /* Synch the tb dependent flags between translator and runtime.  */
@@ -1506,7 +1509,7 @@ static struct decoder_info {
     {{0, 0}, dec_null}
 };
 
-static inline void decode(DisasContext *dc, uint32_t ir)
+static void old_decode(DisasContext *dc, uint32_t ir)
 {
     int i;
 
@@ -1584,6 +1587,7 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
 {
     DisasContext *dc = container_of(dcb, DisasContext, base);
     CPUMBState *env = cs->env_ptr;
+    uint32_t ir;
 
     /* TODO: This should raise an exception, not terminate qemu. */
     if (dc->base.pc_next & 3) {
@@ -1592,7 +1596,10 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
     }
 
     dc->clear_imm = 1;
-    decode(dc, cpu_ldl_code(env, dc->base.pc_next));
+    ir = cpu_ldl_code(env, dc->base.pc_next);
+    if (!decode(dc, ir)) {
+        old_decode(dc, ir);
+    }
     if (dc->clear_imm && (dc->tb_flags & IMM_FLAG)) {
         dc->tb_flags &= ~IMM_FLAG;
         tcg_gen_discard_i32(cpu_imm);
diff --git a/target/microblaze/meson.build b/target/microblaze/meson.build
index b8fe4afe61..639c3f73a8 100644
--- a/target/microblaze/meson.build
+++ b/target/microblaze/meson.build
@@ -1,4 +1,7 @@
+gen = decodetree.process('insns.decode')
+
 microblaze_ss = ss.source_set()
+microblaze_ss.add(gen)
 microblaze_ss.add(files(
   'cpu.c',
   'gdbstub.c',
-- 
2.25.1



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

* [PATCH v2 36/76] target/microblaze: Convert dec_add to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (34 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 35/76] target/microblaze: Add decodetree infrastructure Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 37/76] target/microblaze: Convert dec_sub " Richard Henderson
                   ` (40 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Adds infrastrucure for translation of instructions, which could
not be added before their first use.  Cache a temporary which
represents r0 as the immediate 0 value, or a sink.

Move the special case of opcode_0_illegal from old_decode()
into decodetree as well, lest this get interpreted as add.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  24 ++++
 target/microblaze/translate.c  | 197 ++++++++++++++++++++++++++-------
 2 files changed, 178 insertions(+), 43 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 1ed9ca0731..5f289a446c 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -16,3 +16,27 @@
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, see <http://www.gnu.org/licenses/>.
 #
+
+&typea          rd ra rb
+&typeb          rd ra imm
+
+# Include any IMM prefix in the value reported.
+%extimm         0:s16 !function=typeb_imm
+
+@typea          ...... rd:5 ra:5 rb:5 ... .... ....     &typea
+@typeb          ...... rd:5 ra:5 ................       &typeb imm=%extimm
+
+###
+
+{
+  zero          000000 00000 00000 00000 000 0000 0000
+  add           000000 ..... ..... ..... 000 0000 0000  @typea
+}
+addc            000010 ..... ..... ..... 000 0000 0000  @typea
+addk            000100 ..... ..... ..... 000 0000 0000  @typea
+addkc           000110 ..... ..... ..... 000 0000 0000  @typea
+
+addi            001000 ..... ..... ................     @typeb
+addic           001010 ..... ..... ................     @typeb
+addik           001100 ..... ..... ................     @typeb
+addikc          001110 ..... ..... ................     @typeb
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index e624093745..de822bd7b7 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -58,6 +58,9 @@ typedef struct DisasContext {
     DisasContextBase base;
     MicroBlazeCPU *cpu;
 
+    TCGv_i32 r0;
+    bool r0_set;
+
     /* Decoder.  */
     int type_b;
     uint32_t ir;
@@ -81,6 +84,14 @@ typedef struct DisasContext {
     int abort_at_next_insn;
 } DisasContext;
 
+static int typeb_imm(DisasContext *dc, int x)
+{
+    if (dc->tb_flags & IMM_FLAG) {
+        return deposit32(dc->ext_imm, 0, 16, x);
+    }
+    return x;
+}
+
 /* Include the auto-generated decoder.  */
 #include "decode-insns.c.inc"
 
@@ -176,11 +187,7 @@ static bool trap_userspace(DisasContext *dc, bool cond)
 static int32_t dec_alu_typeb_imm(DisasContext *dc)
 {
     tcg_debug_assert(dc->type_b);
-    if (dc->tb_flags & IMM_FLAG) {
-        return dc->ext_imm | dc->imm;
-    } else {
-        return (int16_t)dc->imm;
-    }
+    return typeb_imm(dc, (int16_t)dc->imm);
 }
 
 static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
@@ -192,44 +199,146 @@ static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
     return &cpu_R[dc->rb];
 }
 
-static void dec_add(DisasContext *dc)
+static TCGv_i32 reg_for_read(DisasContext *dc, int reg)
 {
-    unsigned int k, c;
-    TCGv_i32 cf;
-
-    k = dc->opcode & 4;
-    c = dc->opcode & 2;
-
-    /* Take care of the easy cases first.  */
-    if (k) {
-        /* k - keep carry, no need to update MSR.  */
-        /* If rd == r0, it's a nop.  */
-        if (dc->rd) {
-            tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-
-            if (c) {
-                /* c - Add carry into the result.  */
-                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_msr_c);
-            }
+    if (likely(reg != 0)) {
+        return cpu_R[reg];
+    }
+    if (!dc->r0_set) {
+        if (dc->r0 == NULL) {
+            dc->r0 = tcg_temp_new_i32();
         }
-        return;
+        tcg_gen_movi_i32(dc->r0, 0);
+        dc->r0_set = true;
+    }
+    return dc->r0;
+}
+
+static TCGv_i32 reg_for_write(DisasContext *dc, int reg)
+{
+    if (likely(reg != 0)) {
+        return cpu_R[reg];
+    }
+    if (dc->r0 == NULL) {
+        dc->r0 = tcg_temp_new_i32();
+    }
+    return dc->r0;
+}
+
+static bool do_typea(DisasContext *dc, arg_typea *arg, bool side_effects,
+                     void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32))
+{
+    TCGv_i32 rd, ra, rb;
+
+    if (arg->rd == 0 && !side_effects) {
+        return true;
     }
 
-    /* From now on, we can assume k is zero.  So we need to update MSR.  */
-    /* Extract carry.  */
-    cf = tcg_temp_new_i32();
-    if (c) {
-        tcg_gen_mov_i32(cf, cpu_msr_c);
-    } else {
-        tcg_gen_movi_i32(cf, 0);
+    rd = reg_for_write(dc, arg->rd);
+    ra = reg_for_read(dc, arg->ra);
+    rb = reg_for_read(dc, arg->rb);
+    fn(rd, ra, rb);
+    return true;
+}
+
+static bool do_typeb_imm(DisasContext *dc, arg_typeb *arg, bool side_effects,
+                         void (*fni)(TCGv_i32, TCGv_i32, int32_t))
+{
+    TCGv_i32 rd, ra;
+
+    if (arg->rd == 0 && !side_effects) {
+        return true;
     }
 
-    gen_helper_carry(cpu_msr_c, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
-    if (dc->rd) {
-        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
+    rd = reg_for_write(dc, arg->rd);
+    ra = reg_for_read(dc, arg->ra);
+    fni(rd, ra, arg->imm);
+    return true;
+}
+
+static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
+                         void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32))
+{
+    TCGv_i32 rd, ra, imm;
+
+    if (arg->rd == 0 && !side_effects) {
+        return true;
     }
-    tcg_temp_free_i32(cf);
+
+    rd = reg_for_write(dc, arg->rd);
+    ra = reg_for_read(dc, arg->ra);
+    imm = tcg_const_i32(arg->imm);
+
+    fn(rd, ra, imm);
+
+    tcg_temp_free_i32(imm);
+    return true;
+}
+
+#define DO_TYPEA(NAME, SE, FN) \
+    static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
+    { return do_typea(dc, a, SE, FN); }
+
+#define DO_TYPEBI(NAME, SE, FNI) \
+    static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
+    { return do_typeb_imm(dc, a, SE, FNI); }
+
+#define DO_TYPEBV(NAME, SE, FN) \
+    static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
+    { return do_typeb_val(dc, a, SE, FN); }
+
+/* No input carry, but output carry. */
+static void gen_add(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 zero = tcg_const_i32(0);
+
+    tcg_gen_add2_i32(out, cpu_msr_c, ina, zero, inb, zero);
+
+    tcg_temp_free_i32(zero);
+}
+
+/* Input and output carry. */
+static void gen_addc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 zero = tcg_const_i32(0);
+    TCGv_i32 tmp = tcg_temp_new_i32();
+
+    tcg_gen_add2_i32(tmp, cpu_msr_c, ina, zero, cpu_msr_c, zero);
+    tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
+
+    tcg_temp_free_i32(tmp);
+    tcg_temp_free_i32(zero);
+}
+
+/* Input carry, but no output carry. */
+static void gen_addkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    tcg_gen_add_i32(out, ina, inb);
+    tcg_gen_add_i32(out, out, cpu_msr_c);
+}
+
+DO_TYPEA(add, true, gen_add)
+DO_TYPEA(addc, true, gen_addc)
+DO_TYPEA(addk, false, tcg_gen_add_i32)
+DO_TYPEA(addkc, true, gen_addkc)
+
+DO_TYPEBV(addi, true, gen_add)
+DO_TYPEBV(addic, true, gen_addc)
+DO_TYPEBI(addik, false, tcg_gen_addi_i32)
+DO_TYPEBV(addikc, true, gen_addkc)
+
+static bool trans_zero(DisasContext *dc, arg_zero *arg)
+{
+    /* If opcode_0_illegal, trap.  */
+    if (dc->cpu->cfg.opcode_0_illegal) {
+        trap_illegal(dc, true);
+        return true;
+    }
+    /*
+     * Otherwise, this is "add r0, r0, r0".
+     * Continue to trans_add so that MSR[C] gets cleared.
+     */
+    return false;
 }
 
 static void dec_sub(DisasContext *dc)
@@ -1488,7 +1597,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_ADD, dec_add},
     {DEC_SUB, dec_sub},
     {DEC_AND, dec_and},
     {DEC_XOR, dec_xor},
@@ -1515,12 +1623,6 @@ static void old_decode(DisasContext *dc, uint32_t ir)
 
     dc->ir = ir;
 
-    if (ir == 0) {
-        trap_illegal(dc, dc->cpu->cfg.opcode_0_illegal);
-        /* Don't decode nop/zero instructions any further.  */
-        return;
-    }
-
     /* bit 2 seems to indicate insn type.  */
     dc->type_b = ir & (1 << 29);
 
@@ -1552,6 +1654,8 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
     dc->ext_imm = dc->base.tb->cs_base;
+    dc->r0 = NULL;
+    dc->r0_set = false;
 
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
     dc->base.max_insns = MIN(dc->base.max_insns, bound);
@@ -1600,6 +1704,13 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
     if (!decode(dc, ir)) {
         old_decode(dc, ir);
     }
+
+    if (dc->r0) {
+        tcg_temp_free_i32(dc->r0);
+        dc->r0 = NULL;
+        dc->r0_set = false;
+    }
+
     if (dc->clear_imm && (dc->tb_flags & IMM_FLAG)) {
         dc->tb_flags &= ~IMM_FLAG;
         tcg_gen_discard_i32(cpu_imm);
-- 
2.25.1



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

* [PATCH v2 37/76] target/microblaze: Convert dec_sub to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (35 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 36/76] target/microblaze: Convert dec_add to decodetree Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 38/76] target/microblaze: Implement cmp and cmpu inline Richard Henderson
                   ` (39 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Use tcg_gen_add2_i32 for computing carry.
This removes the last use of helper_carry, so remove that.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h     |   1 -
 target/microblaze/insns.decode |  13 ++++
 target/microblaze/op_helper.c  |  16 -----
 target/microblaze/translate.c  | 110 ++++++++++++++++-----------------
 4 files changed, 65 insertions(+), 75 deletions(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 9309142f8d..988abf7661 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -1,5 +1,4 @@
 DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, i32)
-DEF_HELPER_FLAGS_3(carry, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
 DEF_HELPER_2(cmp, i32, i32, i32)
 DEF_HELPER_2(cmpu, i32, i32, i32)
 
diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 5f289a446c..a611cc83a7 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -40,3 +40,16 @@ addi            001000 ..... ..... ................     @typeb
 addic           001010 ..... ..... ................     @typeb
 addik           001100 ..... ..... ................     @typeb
 addikc          001110 ..... ..... ................     @typeb
+
+cmp             000101 ..... ..... ..... 000 0000 0001  @typea
+cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
+
+rsub            000001 ..... ..... ..... 000 0000 0000  @typea
+rsubc           000011 ..... ..... ..... 000 0000 0000  @typea
+rsubk           000101 ..... ..... ..... 000 0000 0000  @typea
+rsubkc          000111 ..... ..... ..... 000 0000 0000  @typea
+
+rsubi           001001 ..... ..... ................     @typeb
+rsubic          001011 ..... ..... ................     @typeb
+rsubik          001101 ..... ..... ................     @typeb
+rsubikc         001111 ..... ..... ................     @typeb
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index decdca0fd8..9bb6a2ad76 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -69,17 +69,6 @@ void helper_raise_exception(CPUMBState *env, uint32_t index)
     cpu_loop_exit(cs);
 }
 
-static inline uint32_t compute_carry(uint32_t a, uint32_t b, uint32_t cin)
-{
-    uint32_t cout = 0;
-
-    if ((b == ~0) && cin)
-        cout = 1;
-    else if ((~0 - a) < (b + cin))
-        cout = 1;
-    return cout;
-}
-
 uint32_t helper_cmp(uint32_t a, uint32_t b)
 {
     uint32_t t;
@@ -100,11 +89,6 @@ uint32_t helper_cmpu(uint32_t a, uint32_t b)
     return t;
 }
 
-uint32_t helper_carry(uint32_t a, uint32_t b, uint32_t cf)
-{
-    return compute_carry(a, b, cf);
-}
-
 static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
 {
     MicroBlazeCPU *cpu = env_archcpu(env);
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index de822bd7b7..0e7d24ddca 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -327,6 +327,58 @@ DO_TYPEBV(addic, true, gen_addc)
 DO_TYPEBI(addik, false, tcg_gen_addi_i32)
 DO_TYPEBV(addikc, true, gen_addkc)
 
+DO_TYPEA(cmp, false, gen_helper_cmp)
+DO_TYPEA(cmpu, false, gen_helper_cmpu)
+
+/* No input carry, but output carry. */
+static void gen_rsub(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_msr_c, inb, ina);
+    tcg_gen_sub_i32(out, inb, ina);
+}
+
+/* Input and output carry. */
+static void gen_rsubc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 zero = tcg_const_i32(0);
+    TCGv_i32 tmp = tcg_temp_new_i32();
+
+    tcg_gen_not_i32(tmp, ina);
+    tcg_gen_add2_i32(tmp, cpu_msr_c, tmp, zero, cpu_msr_c, zero);
+    tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
+
+    tcg_temp_free_i32(zero);
+    tcg_temp_free_i32(tmp);
+}
+
+/* No input or output carry. */
+static void gen_rsubk(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    tcg_gen_sub_i32(out, inb, ina);
+}
+
+/* Input carry, no output carry. */
+static void gen_rsubkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 nota = tcg_temp_new_i32();
+
+    tcg_gen_not_i32(nota, ina);
+    tcg_gen_add_i32(out, inb, nota);
+    tcg_gen_add_i32(out, out, cpu_msr_c);
+
+    tcg_temp_free_i32(nota);
+}
+
+DO_TYPEA(rsub, true, gen_rsub)
+DO_TYPEA(rsubc, true, gen_rsubc)
+DO_TYPEA(rsubk, false, gen_rsubk)
+DO_TYPEA(rsubkc, true, gen_rsubkc)
+
+DO_TYPEBV(rsubi, true, gen_rsub)
+DO_TYPEBV(rsubic, true, gen_rsubc)
+DO_TYPEBV(rsubik, false, gen_rsubk)
+DO_TYPEBV(rsubikc, true, gen_rsubkc)
+
 static bool trans_zero(DisasContext *dc, arg_zero *arg)
 {
     /* If opcode_0_illegal, trap.  */
@@ -341,63 +393,6 @@ static bool trans_zero(DisasContext *dc, arg_zero *arg)
     return false;
 }
 
-static void dec_sub(DisasContext *dc)
-{
-    unsigned int u, cmp, k, c;
-    TCGv_i32 cf, na;
-
-    u = dc->imm & 2;
-    k = dc->opcode & 4;
-    c = dc->opcode & 2;
-    cmp = (dc->imm & 1) && (!dc->type_b) && k;
-
-    if (cmp) {
-        if (dc->rd) {
-            if (u)
-                gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
-            else
-                gen_helper_cmp(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
-        }
-        return;
-    }
-
-    /* Take care of the easy cases first.  */
-    if (k) {
-        /* k - keep carry, no need to update MSR.  */
-        /* If rd == r0, it's a nop.  */
-        if (dc->rd) {
-            tcg_gen_sub_i32(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
-
-            if (c) {
-                /* c - Add carry into the result.  */
-                tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_msr_c);
-            }
-        }
-        return;
-    }
-
-    /* From now on, we can assume k is zero.  So we need to update MSR.  */
-    /* Extract carry. And complement a into na.  */
-    cf = tcg_temp_new_i32();
-    na = tcg_temp_new_i32();
-    if (c) {
-        tcg_gen_mov_i32(cf, cpu_msr_c);
-    } else {
-        tcg_gen_movi_i32(cf, 1);
-    }
-
-    /* d = b + ~a + c. carry defaults to 1.  */
-    tcg_gen_not_i32(na, cpu_R[dc->ra]);
-
-    gen_helper_carry(cpu_msr_c, na, *(dec_alu_op_b(dc)), cf);
-    if (dc->rd) {
-        tcg_gen_add_i32(cpu_R[dc->rd], na, *(dec_alu_op_b(dc)));
-        tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf);
-    }
-    tcg_temp_free_i32(cf);
-    tcg_temp_free_i32(na);
-}
-
 static void dec_pattern(DisasContext *dc)
 {
     unsigned int mode;
@@ -1597,7 +1592,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_SUB, dec_sub},
     {DEC_AND, dec_and},
     {DEC_XOR, dec_xor},
     {DEC_OR, dec_or},
-- 
2.25.1



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

* [PATCH v2 38/76] target/microblaze: Implement cmp and cmpu inline
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (36 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 37/76] target/microblaze: Convert dec_sub " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 39/76] target/microblaze: Convert dec_pattern to decodetree Richard Henderson
                   ` (38 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

These are simple enough operations; we do not need to
call an out-of-line helper.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h    |  2 --
 target/microblaze/op_helper.c | 20 --------------------
 target/microblaze/translate.c | 24 ++++++++++++++++++++++--
 3 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 988abf7661..6f7f96421f 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -1,6 +1,4 @@
 DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, i32)
-DEF_HELPER_2(cmp, i32, i32, i32)
-DEF_HELPER_2(cmpu, i32, i32, i32)
 
 DEF_HELPER_3(divs, i32, env, i32, i32)
 DEF_HELPER_3(divu, i32, env, i32, i32)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 9bb6a2ad76..f976d112eb 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -69,26 +69,6 @@ void helper_raise_exception(CPUMBState *env, uint32_t index)
     cpu_loop_exit(cs);
 }
 
-uint32_t helper_cmp(uint32_t a, uint32_t b)
-{
-    uint32_t t;
-
-    t = b + ~a + 1;
-    if ((b & 0x80000000) ^ (a & 0x80000000))
-        t = (t & 0x7fffffff) | (b & 0x80000000);
-    return t;
-}
-
-uint32_t helper_cmpu(uint32_t a, uint32_t b)
-{
-    uint32_t t;
-
-    t = b + ~a + 1;
-    if ((b & 0x80000000) ^ (a & 0x80000000))
-        t = (t & 0x7fffffff) | (a & 0x80000000);
-    return t;
-}
-
 static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
 {
     MicroBlazeCPU *cpu = env_archcpu(env);
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 0e7d24ddca..8da477457d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -327,8 +327,28 @@ DO_TYPEBV(addic, true, gen_addc)
 DO_TYPEBI(addik, false, tcg_gen_addi_i32)
 DO_TYPEBV(addikc, true, gen_addkc)
 
-DO_TYPEA(cmp, false, gen_helper_cmp)
-DO_TYPEA(cmpu, false, gen_helper_cmpu)
+static void gen_cmp(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 lt = tcg_temp_new_i32();
+
+    tcg_gen_setcond_i32(TCG_COND_LT, lt, inb, ina);
+    tcg_gen_sub_i32(out, inb, ina);
+    tcg_gen_deposit_i32(out, out, lt, 31, 1);
+    tcg_temp_free_i32(lt);
+}
+
+static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 lt = tcg_temp_new_i32();
+
+    tcg_gen_setcond_i32(TCG_COND_LTU, lt, inb, ina);
+    tcg_gen_sub_i32(out, inb, ina);
+    tcg_gen_deposit_i32(out, out, lt, 31, 1);
+    tcg_temp_free_i32(lt);
+}
+
+DO_TYPEA(cmp, false, gen_cmp)
+DO_TYPEA(cmpu, false, gen_cmpu)
 
 /* No input carry, but output carry. */
 static void gen_rsub(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-- 
2.25.1



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

* [PATCH v2 39/76] target/microblaze: Convert dec_pattern to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (37 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 38/76] target/microblaze: Implement cmp and cmpu inline Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor " Richard Henderson
                   ` (37 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  4 ++
 target/microblaze/translate.c  | 67 +++++++++-------------------------
 2 files changed, 22 insertions(+), 49 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index a611cc83a7..16519f05dc 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -44,6 +44,10 @@ addikc          001110 ..... ..... ................     @typeb
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
 cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 
+pcmpbf          100000 ..... ..... ..... 100 0000 0000  @typea
+pcmpeq          100010 ..... ..... ..... 100 0000 0000  @typea
+pcmpne          100011 ..... ..... ..... 100 0000 0000  @typea
+
 rsub            000001 ..... ..... ..... 000 0000 0000  @typea
 rsubc           000011 ..... ..... ..... 000 0000 0000  @typea
 rsubk           000101 ..... ..... ..... 000 0000 0000  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 8da477457d..7ebf0e1e7d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -279,6 +279,10 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
     static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
     { return do_typea(dc, a, SE, FN); }
 
+#define DO_TYPEA_CFG(NAME, CFG, SE, FN) \
+    static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
+    { return dc->cpu->cfg.CFG && do_typea(dc, a, SE, FN); }
+
 #define DO_TYPEBI(NAME, SE, FNI) \
     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
     { return do_typeb_imm(dc, a, SE, FNI); }
@@ -350,6 +354,20 @@ static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 DO_TYPEA(cmp, false, gen_cmp)
 DO_TYPEA(cmpu, false, gen_cmpu)
 
+static void gen_pcmpeq(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    tcg_gen_setcond_i32(TCG_COND_EQ, out, ina, inb);
+}
+
+static void gen_pcmpne(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    tcg_gen_setcond_i32(TCG_COND_NE, out, ina, inb);
+}
+
+DO_TYPEA_CFG(pcmpbf, use_pcmp_instr, false, gen_helper_pcmpbf)
+DO_TYPEA_CFG(pcmpeq, use_pcmp_instr, false, gen_pcmpeq)
+DO_TYPEA_CFG(pcmpne, use_pcmp_instr, false, gen_pcmpne)
+
 /* No input carry, but output carry. */
 static void gen_rsub(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
@@ -413,49 +431,10 @@ static bool trans_zero(DisasContext *dc, arg_zero *arg)
     return false;
 }
 
-static void dec_pattern(DisasContext *dc)
-{
-    unsigned int mode;
-
-    if (trap_illegal(dc, !dc->cpu->cfg.use_pcmp_instr)) {
-        return;
-    }
-
-    mode = dc->opcode & 3;
-    switch (mode) {
-        case 0:
-            /* pcmpbf.  */
-            if (dc->rd)
-                gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
-            break;
-        case 2:
-            if (dc->rd) {
-                tcg_gen_setcond_i32(TCG_COND_EQ, cpu_R[dc->rd],
-                                   cpu_R[dc->ra], cpu_R[dc->rb]);
-            }
-            break;
-        case 3:
-            if (dc->rd) {
-                tcg_gen_setcond_i32(TCG_COND_NE, cpu_R[dc->rd],
-                                   cpu_R[dc->ra], cpu_R[dc->rb]);
-            }
-            break;
-        default:
-            cpu_abort(CPU(dc->cpu),
-                      "unsupported pattern insn opcode=%x\n", dc->opcode);
-            break;
-    }
-}
-
 static void dec_and(DisasContext *dc)
 {
     unsigned int not;
 
-    if (!dc->type_b && (dc->imm & (1 << 10))) {
-        dec_pattern(dc);
-        return;
-    }
-
     not = dc->opcode & (1 << 1);
 
     if (!dc->rd)
@@ -469,22 +448,12 @@ static void dec_and(DisasContext *dc)
 
 static void dec_or(DisasContext *dc)
 {
-    if (!dc->type_b && (dc->imm & (1 << 10))) {
-        dec_pattern(dc);
-        return;
-    }
-
     if (dc->rd)
         tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
 
 static void dec_xor(DisasContext *dc)
 {
-    if (!dc->type_b && (dc->imm & (1 << 10))) {
-        dec_pattern(dc);
-        return;
-    }
-
     if (dc->rd)
         tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
 }
-- 
2.25.1



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

* [PATCH v2 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (38 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 39/76] target/microblaze: Convert dec_pattern to decodetree Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 41/76] target/microblaze: Convert dec_mul " Richard Henderson
                   ` (36 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode | 12 +++++++++
 target/microblaze/translate.c  | 46 ++++++++++++----------------------
 2 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 16519f05dc..93bd51c78b 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -41,9 +41,18 @@ addic           001010 ..... ..... ................     @typeb
 addik           001100 ..... ..... ................     @typeb
 addikc          001110 ..... ..... ................     @typeb
 
+and             100001 ..... ..... ..... 000 0000 0000  @typea
+andi            101001 ..... ..... ................     @typeb
+
+andn            100011 ..... ..... ..... 000 0000 0000  @typea
+andni           101011 ..... ..... ................     @typeb
+
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
 cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 
+or              100000 ..... ..... ..... 000 0000 0000  @typea
+ori             101000 ..... ..... ................     @typeb
+
 pcmpbf          100000 ..... ..... ..... 100 0000 0000  @typea
 pcmpeq          100010 ..... ..... ..... 100 0000 0000  @typea
 pcmpne          100011 ..... ..... ..... 100 0000 0000  @typea
@@ -57,3 +66,6 @@ rsubi           001001 ..... ..... ................     @typeb
 rsubic          001011 ..... ..... ................     @typeb
 rsubik          001101 ..... ..... ................     @typeb
 rsubikc         001111 ..... ..... ................     @typeb
+
+xor             100010 ..... ..... ..... 000 0000 0000  @typea
+xori            101010 ..... ..... ................     @typeb
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 7ebf0e1e7d..a143f17e9d 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -331,6 +331,16 @@ DO_TYPEBV(addic, true, gen_addc)
 DO_TYPEBI(addik, false, tcg_gen_addi_i32)
 DO_TYPEBV(addikc, true, gen_addkc)
 
+static void gen_andni(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
+{
+    tcg_gen_andi_i32(out, ina, ~imm);
+}
+
+DO_TYPEA(and, false, tcg_gen_and_i32)
+DO_TYPEBI(andi, false, tcg_gen_andi_i32)
+DO_TYPEA(andn, false, tcg_gen_andc_i32)
+DO_TYPEBI(andni, false, gen_andni)
+
 static void gen_cmp(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
     TCGv_i32 lt = tcg_temp_new_i32();
@@ -354,6 +364,9 @@ static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 DO_TYPEA(cmp, false, gen_cmp)
 DO_TYPEA(cmpu, false, gen_cmpu)
 
+DO_TYPEA(or, false, tcg_gen_or_i32)
+DO_TYPEBI(ori, false, tcg_gen_ori_i32)
+
 static void gen_pcmpeq(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
     tcg_gen_setcond_i32(TCG_COND_EQ, out, ina, inb);
@@ -417,6 +430,9 @@ DO_TYPEBV(rsubic, true, gen_rsubc)
 DO_TYPEBV(rsubik, false, gen_rsubk)
 DO_TYPEBV(rsubikc, true, gen_rsubkc)
 
+DO_TYPEA(xor, false, tcg_gen_xor_i32)
+DO_TYPEBI(xori, false, tcg_gen_xori_i32)
+
 static bool trans_zero(DisasContext *dc, arg_zero *arg)
 {
     /* If opcode_0_illegal, trap.  */
@@ -431,33 +447,6 @@ static bool trans_zero(DisasContext *dc, arg_zero *arg)
     return false;
 }
 
-static void dec_and(DisasContext *dc)
-{
-    unsigned int not;
-
-    not = dc->opcode & (1 << 1);
-
-    if (!dc->rd)
-        return;
-
-    if (not) {
-        tcg_gen_andc_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-    } else
-        tcg_gen_and_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-}
-
-static void dec_or(DisasContext *dc)
-{
-    if (dc->rd)
-        tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-}
-
-static void dec_xor(DisasContext *dc)
-{
-    if (dc->rd)
-        tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-}
-
 static void msr_read(DisasContext *dc, TCGv_i32 d)
 {
     TCGv_i32 t;
@@ -1581,9 +1570,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_AND, dec_and},
-    {DEC_XOR, dec_xor},
-    {DEC_OR, dec_or},
     {DEC_BIT, dec_bit},
     {DEC_BARREL, dec_barrel},
     {DEC_LD, dec_load},
-- 
2.25.1



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

* [PATCH v2 41/76] target/microblaze: Convert dec_mul to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (39 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 42/76] target/microblaze: Convert dec_div " Richard Henderson
                   ` (35 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  6 +++
 target/microblaze/translate.c  | 77 ++++++++++++++--------------------
 2 files changed, 37 insertions(+), 46 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 93bd51c78b..1a2e22e44a 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -50,6 +50,12 @@ andni           101011 ..... ..... ................     @typeb
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
 cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 
+mul             010000 ..... ..... ..... 000 0000 0000  @typea
+mulh            010000 ..... ..... ..... 000 0000 0001  @typea
+mulhu           010000 ..... ..... ..... 000 0000 0011  @typea
+mulhsu          010000 ..... ..... ..... 000 0000 0010  @typea
+muli            011000 ..... ..... ................     @typeb
+
 or              100000 ..... ..... ..... 000 0000 0000  @typea
 ori             101000 ..... ..... ................     @typeb
 
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a143f17e9d..617e208583 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -287,6 +287,10 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
     { return do_typeb_imm(dc, a, SE, FNI); }
 
+#define DO_TYPEBI_CFG(NAME, CFG, SE, FNI) \
+    static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
+    { return dc->cpu->cfg.CFG && do_typeb_imm(dc, a, SE, FNI); }
+
 #define DO_TYPEBV(NAME, SE, FN) \
     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
     { return do_typeb_val(dc, a, SE, FN); }
@@ -364,6 +368,33 @@ static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 DO_TYPEA(cmp, false, gen_cmp)
 DO_TYPEA(cmpu, false, gen_cmpu)
 
+static void gen_mulh(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_muls2_i32(tmp, out, ina, inb);
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_mulhu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_mulu2_i32(tmp, out, ina, inb);
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_mulhsu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_mulsu2_i32(tmp, out, ina, inb);
+    tcg_temp_free_i32(tmp);
+}
+
+DO_TYPEA_CFG(mul, use_hw_mul, false, tcg_gen_mul_i32)
+DO_TYPEA_CFG(mulh, use_hw_mul >= 2, false, gen_mulh)
+DO_TYPEA_CFG(mulhu, use_hw_mul >= 2, false, gen_mulhu)
+DO_TYPEA_CFG(mulhsu, use_hw_mul >= 2, false, gen_mulhsu)
+DO_TYPEBI_CFG(muli, use_hw_mul, false, tcg_gen_muli_i32)
+
 DO_TYPEA(or, false, tcg_gen_or_i32)
 DO_TYPEBI(ori, false, tcg_gen_ori_i32)
 
@@ -652,51 +683,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-/* Multiplier unit.  */
-static void dec_mul(DisasContext *dc)
-{
-    TCGv_i32 tmp;
-    unsigned int subcode;
-
-    if (trap_illegal(dc, !dc->cpu->cfg.use_hw_mul)) {
-        return;
-    }
-
-    subcode = dc->imm & 3;
-
-    if (dc->type_b) {
-        tcg_gen_mul_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
-        return;
-    }
-
-    /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2.  */
-    if (subcode >= 1 && subcode <= 3 && dc->cpu->cfg.use_hw_mul < 2) {
-        /* nop??? */
-    }
-
-    tmp = tcg_temp_new_i32();
-    switch (subcode) {
-        case 0:
-            tcg_gen_mul_i32(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
-            break;
-        case 1:
-            tcg_gen_muls2_i32(tmp, cpu_R[dc->rd],
-                              cpu_R[dc->ra], cpu_R[dc->rb]);
-            break;
-        case 2:
-            tcg_gen_mulsu2_i32(tmp, cpu_R[dc->rd],
-                               cpu_R[dc->ra], cpu_R[dc->rb]);
-            break;
-        case 3:
-            tcg_gen_mulu2_i32(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
-            break;
-        default:
-            cpu_abort(CPU(dc->cpu), "unknown MUL insn %x\n", subcode);
-            break;
-    }
-    tcg_temp_free_i32(tmp);
-}
-
 /* Div unit.  */
 static void dec_div(DisasContext *dc)
 {
@@ -1579,7 +1565,6 @@ static struct decoder_info {
     {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
     {DEC_FPU, dec_fpu},
-    {DEC_MUL, dec_mul},
     {DEC_DIV, dec_div},
     {DEC_MSR, dec_msr},
     {DEC_STREAM, dec_stream},
-- 
2.25.1



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

* [PATCH v2 42/76] target/microblaze: Convert dec_div to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (40 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 41/76] target/microblaze: Convert dec_mul " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 43/76] target/microblaze: Unwind properly when raising divide-by-zero Richard Henderson
                   ` (34 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  3 +++
 target/microblaze/translate.c  | 35 +++++++++++++---------------------
 2 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 1a2e22e44a..b2dcbdf784 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -50,6 +50,9 @@ andni           101011 ..... ..... ................     @typeb
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
 cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 
+idiv            010010 ..... ..... ..... 000 0000 0000  @typea
+idivu           010010 ..... ..... ..... 000 0000 0010  @typea
+
 mul             010000 ..... ..... ..... 000 0000 0000  @typea
 mulh            010000 ..... ..... ..... 000 0000 0001  @typea
 mulhu           010000 ..... ..... ..... 000 0000 0011  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 617e208583..9763b9d77c 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -368,6 +368,19 @@ static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 DO_TYPEA(cmp, false, gen_cmp)
 DO_TYPEA(cmpu, false, gen_cmpu)
 
+static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    gen_helper_divs(out, cpu_env, inb, ina);
+}
+
+static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    gen_helper_divu(out, cpu_env, inb, ina);
+}
+
+DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
+DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)
+
 static void gen_mulh(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
     TCGv_i32 tmp = tcg_temp_new_i32();
@@ -683,27 +696,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-/* Div unit.  */
-static void dec_div(DisasContext *dc)
-{
-    unsigned int u;
-
-    u = dc->imm & 2; 
-
-    if (trap_illegal(dc, !dc->cpu->cfg.use_div)) {
-        return;
-    }
-
-    if (u)
-        gen_helper_divu(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
-                        cpu_R[dc->ra]);
-    else
-        gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
-                        cpu_R[dc->ra]);
-    if (!dc->rd)
-        tcg_gen_movi_i32(cpu_R[dc->rd], 0);
-}
-
 static void dec_barrel(DisasContext *dc)
 {
     TCGv_i32 t0;
@@ -1565,7 +1557,6 @@ static struct decoder_info {
     {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
     {DEC_FPU, dec_fpu},
-    {DEC_DIV, dec_div},
     {DEC_MSR, dec_msr},
     {DEC_STREAM, dec_stream},
     {{0, 0}, dec_null}
-- 
2.25.1



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

* [PATCH v2 43/76] target/microblaze: Unwind properly when raising divide-by-zero
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (41 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 42/76] target/microblaze: Convert dec_div " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 44/76] target/microblaze: Convert dec_bit to decodetree Richard Henderson
                   ` (33 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Restore the correct pc when raising divide-by-zero.  Also, the
MSR[DZO] bit is sticky -- it is not cleared with a successful divide.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h    |  4 ++--
 target/microblaze/op_helper.c | 23 ++++++++++++-----------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 6f7f96421f..79e1e8ecc7 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -1,7 +1,7 @@
 DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, i32)
 
-DEF_HELPER_3(divs, i32, env, i32, i32)
-DEF_HELPER_3(divu, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(divs, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
 
 DEF_HELPER_3(fadd, i32, env, i32, i32)
 DEF_HELPER_3(frsub, i32, env, i32, i32)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index f976d112eb..d99d98051a 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -69,26 +69,27 @@ void helper_raise_exception(CPUMBState *env, uint32_t index)
     cpu_loop_exit(cs);
 }
 
-static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
+static bool check_divz(CPUMBState *env, uint32_t a, uint32_t b, uintptr_t ra)
 {
-    MicroBlazeCPU *cpu = env_archcpu(env);
-
-    if (b == 0) {
+    if (unlikely(b == 0)) {
         env->msr |= MSR_DZ;
 
-        if ((env->msr & MSR_EE) && cpu->cfg.div_zero_exception) {
+        if ((env->msr & MSR_EE) &&
+            env_archcpu(env)->cfg.div_zero_exception) {
+            CPUState *cs = env_cpu(env);
+
             env->esr = ESR_EC_DIVZERO;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+            cs->exception_index = EXCP_HW_EXCP;
+            cpu_loop_exit_restore(cs, ra);
         }
-        return 0;
+        return false;
     }
-    env->msr &= ~MSR_DZ;
-    return 1;
+    return true;
 }
 
 uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
 {
-    if (!div_prepare(env, a, b)) {
+    if (!check_divz(env, a, b, GETPC())) {
         return 0;
     }
     return (int32_t)a / (int32_t)b;
@@ -96,7 +97,7 @@ uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
 
 uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
 {
-    if (!div_prepare(env, a, b)) {
+    if (!check_divz(env, a, b, GETPC())) {
         return 0;
     }
     return a / b;
-- 
2.25.1



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

* [PATCH v2 44/76] target/microblaze: Convert dec_bit to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (42 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 43/76] target/microblaze: Unwind properly when raising divide-by-zero Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 45/76] target/microblaze: Convert dec_barrel " Richard Henderson
                   ` (32 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  20 +++++
 target/microblaze/translate.c  | 148 +++++++++++++++++----------------
 2 files changed, 95 insertions(+), 73 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index b2dcbdf784..d265e36044 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -17,6 +17,7 @@
 # License along with this library; if not, see <http://www.gnu.org/licenses/>.
 #
 
+&typea0         rd ra
 &typea          rd ra rb
 &typeb          rd ra imm
 
@@ -26,6 +27,9 @@
 @typea          ...... rd:5 ra:5 rb:5 ... .... ....     &typea
 @typeb          ...... rd:5 ra:5 ................       &typeb imm=%extimm
 
+# Officially typea, but with rb==0, which is not used.
+@typea0         ...... rd:5 ra:5 ................       &typea0
+
 ###
 
 {
@@ -47,6 +51,8 @@ andi            101001 ..... ..... ................     @typeb
 andn            100011 ..... ..... ..... 000 0000 0000  @typea
 andni           101011 ..... ..... ................     @typeb
 
+clz             100100 ..... ..... 00000 000 1110 0000  @typea0
+
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
 cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 
@@ -76,5 +82,19 @@ rsubic          001011 ..... ..... ................     @typeb
 rsubik          001101 ..... ..... ................     @typeb
 rsubikc         001111 ..... ..... ................     @typeb
 
+sext8           100100 ..... ..... 00000 000 0110 0000  @typea0
+sext16          100100 ..... ..... 00000 000 0110 0001  @typea0
+
+sra             100100 ..... ..... 00000 000 0000 0001  @typea0
+src             100100 ..... ..... 00000 000 0010 0001  @typea0
+srl             100100 ..... ..... 00000 000 0100 0001  @typea0
+
+swapb           100100 ..... ..... 00000 001 1110 0000  @typea0
+swaph           100100 ..... ..... 00000 001 1110 0010  @typea0
+
+# Cache operations have no effect in qemu: discard the arguments.
+wdic            100100 00000 ----- ----- -00 -11- 01-0  # wdc
+wdic            100100 00000 ----- ----- 000 0110 1000  # wic
+
 xor             100010 ..... ..... ..... 000 0000 0000  @typea
 xori            101010 ..... ..... ................     @typeb
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9763b9d77c..2d57f76548 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -241,6 +241,21 @@ static bool do_typea(DisasContext *dc, arg_typea *arg, bool side_effects,
     return true;
 }
 
+static bool do_typea0(DisasContext *dc, arg_typea0 *arg, bool side_effects,
+                      void (*fn)(TCGv_i32, TCGv_i32))
+{
+    TCGv_i32 rd, ra;
+
+    if (arg->rd == 0 && !side_effects) {
+        return true;
+    }
+
+    rd = reg_for_write(dc, arg->rd);
+    ra = reg_for_read(dc, arg->ra);
+    fn(rd, ra);
+    return true;
+}
+
 static bool do_typeb_imm(DisasContext *dc, arg_typeb *arg, bool side_effects,
                          void (*fni)(TCGv_i32, TCGv_i32, int32_t))
 {
@@ -283,6 +298,14 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
     static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
     { return dc->cpu->cfg.CFG && do_typea(dc, a, SE, FN); }
 
+#define DO_TYPEA0(NAME, SE, FN) \
+    static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
+    { return do_typea0(dc, a, SE, FN); }
+
+#define DO_TYPEA0_CFG(NAME, CFG, SE, FN) \
+    static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
+    { return dc->cpu->cfg.CFG && do_typea0(dc, a, SE, FN); }
+
 #define DO_TYPEBI(NAME, SE, FNI) \
     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
     { return do_typeb_imm(dc, a, SE, FNI); }
@@ -345,6 +368,13 @@ DO_TYPEBI(andi, false, tcg_gen_andi_i32)
 DO_TYPEA(andn, false, tcg_gen_andc_i32)
 DO_TYPEBI(andni, false, gen_andni)
 
+static void gen_clz(TCGv_i32 out, TCGv_i32 ina)
+{
+    tcg_gen_clzi_i32(out, ina, 32);
+}
+
+DO_TYPEA0_CFG(clz, use_pcmp_instr, false, gen_clz)
+
 static void gen_cmp(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
     TCGv_i32 lt = tcg_temp_new_i32();
@@ -474,6 +504,51 @@ DO_TYPEBV(rsubic, true, gen_rsubc)
 DO_TYPEBV(rsubik, false, gen_rsubk)
 DO_TYPEBV(rsubikc, true, gen_rsubkc)
 
+DO_TYPEA0(sext8, false, tcg_gen_ext8s_i32)
+DO_TYPEA0(sext16, false, tcg_gen_ext16s_i32)
+
+static void gen_sra(TCGv_i32 out, TCGv_i32 ina)
+{
+    tcg_gen_andi_i32(cpu_msr_c, ina, 1);
+    tcg_gen_sari_i32(out, ina, 1);
+}
+
+static void gen_src(TCGv_i32 out, TCGv_i32 ina)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+
+    tcg_gen_mov_i32(tmp, cpu_msr_c);
+    tcg_gen_andi_i32(cpu_msr_c, ina, 1);
+    tcg_gen_extract2_i32(out, ina, tmp, 1);
+
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_srl(TCGv_i32 out, TCGv_i32 ina)
+{
+    tcg_gen_andi_i32(cpu_msr_c, ina, 1);
+    tcg_gen_shri_i32(out, ina, 1);
+}
+
+DO_TYPEA0(sra, false, gen_sra)
+DO_TYPEA0(src, false, gen_src)
+DO_TYPEA0(srl, false, gen_srl)
+
+static void gen_swaph(TCGv_i32 out, TCGv_i32 ina)
+{
+    tcg_gen_rotri_i32(out, ina, 16);
+}
+
+DO_TYPEA0(swapb, false, tcg_gen_bswap32_i32)
+DO_TYPEA0(swaph, false, gen_swaph)
+
+static bool trans_wdic(DisasContext *dc, arg_wdic *a)
+{
+    /* Cache operations are nops: only check for supervisor mode.  */
+    trap_userspace(dc, true);
+    return true;
+}
+
 DO_TYPEA(xor, false, tcg_gen_xor_i32)
 DO_TYPEBI(xori, false, tcg_gen_xori_i32)
 
@@ -754,78 +829,6 @@ static void dec_barrel(DisasContext *dc)
     }
 }
 
-static void dec_bit(DisasContext *dc)
-{
-    CPUState *cs = CPU(dc->cpu);
-    TCGv_i32 t0;
-    unsigned int op;
-
-    op = dc->ir & ((1 << 9) - 1);
-    switch (op) {
-        case 0x21:
-            /* src.  */
-            t0 = tcg_temp_new_i32();
-
-            tcg_gen_shli_i32(t0, cpu_msr_c, 31);
-            tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1);
-            if (dc->rd) {
-                tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
-                tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->rd], t0);
-            }
-            tcg_temp_free_i32(t0);
-            break;
-
-        case 0x1:
-        case 0x41:
-            /* srl.  */
-            tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1);
-            if (dc->rd) {
-                if (op == 0x41)
-                    tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
-                else
-                    tcg_gen_sari_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1);
-            }
-            break;
-        case 0x60:
-            tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
-            break;
-        case 0x61:
-            tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
-            break;
-        case 0x64:
-        case 0x66:
-        case 0x74:
-        case 0x76:
-            /* wdc.  */
-            trap_userspace(dc, true);
-            break;
-        case 0x68:
-            /* wic.  */
-            trap_userspace(dc, true);
-            break;
-        case 0xe0:
-            if (trap_illegal(dc, !dc->cpu->cfg.use_pcmp_instr)) {
-                return;
-            }
-            if (dc->cpu->cfg.use_pcmp_instr) {
-                tcg_gen_clzi_i32(cpu_R[dc->rd], cpu_R[dc->ra], 32);
-            }
-            break;
-        case 0x1e0:
-            /* swapb */
-            tcg_gen_bswap32_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
-            break;
-        case 0x1e2:
-            /*swaph */
-            tcg_gen_rotri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 16);
-            break;
-        default:
-            cpu_abort(cs, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
-                      (uint32_t)dc->base.pc_next, op, dc->rd, dc->ra, dc->rb);
-            break;
-    }
-}
-
 static inline void sync_jmpstate(DisasContext *dc)
 {
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
@@ -1548,7 +1551,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_BIT, dec_bit},
     {DEC_BARREL, dec_barrel},
     {DEC_LD, dec_load},
     {DEC_ST, dec_store},
-- 
2.25.1



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

* [PATCH v2 45/76] target/microblaze: Convert dec_barrel to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (43 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 44/76] target/microblaze: Convert dec_bit to decodetree Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:18 ` [PATCH v2 46/76] target/microblaze: Convert dec_imm " Richard Henderson
                   ` (31 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  20 ++++++
 target/microblaze/translate.c  | 125 +++++++++++++++++----------------
 2 files changed, 86 insertions(+), 59 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index d265e36044..4644defbfe 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -30,6 +30,15 @@
 # Officially typea, but with rb==0, which is not used.
 @typea0         ...... rd:5 ra:5 ................       &typea0
 
+# Officially typeb, but any immediate extension is unused.
+@typeb_bs       ...... rd:5 ra:5 ..... ...... imm:5     &typeb
+
+# For convenience, extract the two imm_w/imm_s fields, then pack
+# them back together as "imm".  Doing this makes it easiest to
+# match the required zero at bit 5.
+%ieimm          6:5 0:5
+@typeb_ie       ...... rd:5 ra:5 ..... ..... . .....    &typeb imm=%ieimm
+
 ###
 
 {
@@ -51,6 +60,17 @@ andi            101001 ..... ..... ................     @typeb
 andn            100011 ..... ..... ..... 000 0000 0000  @typea
 andni           101011 ..... ..... ................     @typeb
 
+bsrl            010001 ..... ..... ..... 000 0000 0000  @typea
+bsra            010001 ..... ..... ..... 010 0000 0000  @typea
+bsll            010001 ..... ..... ..... 100 0000 0000  @typea
+
+bsrli           011001 ..... ..... 00000 000000 .....   @typeb_bs
+bsrai           011001 ..... ..... 00000 010000 .....   @typeb_bs
+bslli           011001 ..... ..... 00000 100000 .....   @typeb_bs
+
+bsefi           011001 ..... ..... 01000 .....0 .....   @typeb_ie
+bsifi           011001 ..... ..... 10000 .....0 .....   @typeb_ie
+
 clz             100100 ..... ..... 00000 000 1110 0000  @typea0
 
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 2d57f76548..964525f75e 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -368,6 +368,72 @@ DO_TYPEBI(andi, false, tcg_gen_andi_i32)
 DO_TYPEA(andn, false, tcg_gen_andc_i32)
 DO_TYPEBI(andni, false, gen_andni)
 
+static void gen_bsra(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_andi_i32(tmp, inb, 31);
+    tcg_gen_sar_i32(out, ina, tmp);
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_bsrl(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_andi_i32(tmp, inb, 31);
+    tcg_gen_shr_i32(out, ina, tmp);
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_bsll(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_andi_i32(tmp, inb, 31);
+    tcg_gen_shl_i32(out, ina, tmp);
+    tcg_temp_free_i32(tmp);
+}
+
+static void gen_bsefi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
+{
+    /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
+    int imm_w = extract32(imm, 5, 5);
+    int imm_s = extract32(imm, 0, 5);
+
+    if (imm_w + imm_s > 32 || imm_w == 0) {
+        /* These inputs have an undefined behavior.  */
+        qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
+                      imm_w, imm_s);
+    } else {
+        tcg_gen_extract_i32(out, ina, imm_s, imm_w);
+    }
+}
+
+static void gen_bsifi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
+{
+    /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
+    int imm_w = extract32(imm, 5, 5);
+    int imm_s = extract32(imm, 0, 5);
+    int width = imm_w - imm_s + 1;
+
+    if (imm_w < imm_s) {
+        /* These inputs have an undefined behavior.  */
+        qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
+                      imm_w, imm_s);
+    } else {
+        tcg_gen_deposit_i32(out, out, ina, imm_s, width);
+    }
+}
+
+DO_TYPEA_CFG(bsra, use_barrel, false, gen_bsra)
+DO_TYPEA_CFG(bsrl, use_barrel, false, gen_bsrl)
+DO_TYPEA_CFG(bsll, use_barrel, false, gen_bsll)
+
+DO_TYPEBI_CFG(bsrai, use_barrel, false, tcg_gen_sari_i32)
+DO_TYPEBI_CFG(bsrli, use_barrel, false, tcg_gen_shri_i32)
+DO_TYPEBI_CFG(bslli, use_barrel, false, tcg_gen_shli_i32)
+
+DO_TYPEBI_CFG(bsefi, use_barrel, false, gen_bsefi)
+DO_TYPEBI_CFG(bsifi, use_barrel, false, gen_bsifi)
+
 static void gen_clz(TCGv_i32 out, TCGv_i32 ina)
 {
     tcg_gen_clzi_i32(out, ina, 32);
@@ -771,64 +837,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-static void dec_barrel(DisasContext *dc)
-{
-    TCGv_i32 t0;
-    unsigned int imm_w, imm_s;
-    bool s, t, e = false, i = false;
-
-    if (trap_illegal(dc, !dc->cpu->cfg.use_barrel)) {
-        return;
-    }
-
-    if (dc->type_b) {
-        /* Insert and extract are only available in immediate mode.  */
-        i = extract32(dc->imm, 15, 1);
-        e = extract32(dc->imm, 14, 1);
-    }
-    s = extract32(dc->imm, 10, 1);
-    t = extract32(dc->imm, 9, 1);
-    imm_w = extract32(dc->imm, 6, 5);
-    imm_s = extract32(dc->imm, 0, 5);
-
-    if (e) {
-        if (imm_w + imm_s > 32 || imm_w == 0) {
-            /* These inputs have an undefined behavior.  */
-            qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
-                          imm_w, imm_s);
-        } else {
-            tcg_gen_extract_i32(cpu_R[dc->rd], cpu_R[dc->ra], imm_s, imm_w);
-        }
-    } else if (i) {
-        int width = imm_w - imm_s + 1;
-
-        if (imm_w < imm_s) {
-            /* These inputs have an undefined behavior.  */
-            qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
-                          imm_w, imm_s);
-        } else {
-            tcg_gen_deposit_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_R[dc->ra],
-                                imm_s, width);
-        }
-    } else {
-        t0 = tcg_temp_new_i32();
-
-        tcg_gen_mov_i32(t0, *(dec_alu_op_b(dc)));
-        tcg_gen_andi_i32(t0, t0, 31);
-
-        if (s) {
-            tcg_gen_shl_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
-        } else {
-            if (t) {
-                tcg_gen_sar_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
-            } else {
-                tcg_gen_shr_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
-            }
-        }
-        tcg_temp_free_i32(t0);
-    }
-}
-
 static inline void sync_jmpstate(DisasContext *dc)
 {
     if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
@@ -1551,7 +1559,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_BARREL, dec_barrel},
     {DEC_LD, dec_load},
     {DEC_ST, dec_store},
     {DEC_IMM, dec_imm},
-- 
2.25.1



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

* [PATCH v2 46/76] target/microblaze: Convert dec_imm to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (44 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 45/76] target/microblaze: Convert dec_barrel " Richard Henderson
@ 2020-08-28 14:18 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 47/76] target/microblaze: Convert dec_fpu " Richard Henderson
                   ` (30 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  2 ++
 target/microblaze/translate.c  | 18 +++++++++---------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 4644defbfe..ad15c16f9b 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -79,6 +79,8 @@ cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 idiv            010010 ..... ..... ..... 000 0000 0000  @typea
 idivu           010010 ..... ..... ..... 000 0000 0010  @typea
 
+imm             101100 00000 00000 imm:16
+
 mul             010000 ..... ..... ..... 000 0000 0000  @typea
 mulh            010000 ..... ..... ..... 000 0000 0001  @typea
 mulhu           010000 ..... ..... ..... 000 0000 0011  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 964525f75e..54de136a16 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -477,6 +477,15 @@ static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
 DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)
 
+static bool trans_imm(DisasContext *dc, arg_imm *arg)
+{
+    dc->ext_imm = arg->imm << 16;
+    tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
+    dc->tb_flags |= IMM_FLAG;
+    dc->clear_imm = 0;
+    return true;
+}
+
 static void gen_mulh(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
     TCGv_i32 tmp = tcg_temp_new_i32();
@@ -848,14 +857,6 @@ static inline void sync_jmpstate(DisasContext *dc)
     }
 }
 
-static void dec_imm(DisasContext *dc)
-{
-    dc->ext_imm = dc->imm << 16;
-    tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
-    dc->tb_flags |= IMM_FLAG;
-    dc->clear_imm = 0;
-}
-
 static inline void compute_ldst_addr(DisasContext *dc, bool ea, TCGv t)
 {
     /* Should be set to true if r1 is used by loadstores.  */
@@ -1561,7 +1562,6 @@ static struct decoder_info {
 } decinfo[] = {
     {DEC_LD, dec_load},
     {DEC_ST, dec_store},
-    {DEC_IMM, dec_imm},
     {DEC_BR, dec_br},
     {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
-- 
2.25.1



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

* [PATCH v2 47/76] target/microblaze: Convert dec_fpu to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (45 preceding siblings ...)
  2020-08-28 14:18 ` [PATCH v2 46/76] target/microblaze: Convert dec_imm " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 48/76] target/microblaze: Fix cpu unwind for fpu exceptions Richard Henderson
                   ` (29 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The current dec_check_fpuv2 test, raising an FPU exception for
an unimplemented instruction, appears to be contradictory to
the manual.  Drop that and merely check use_fpu == 2.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  19 +++++
 target/microblaze/translate.c  | 152 +++++++++------------------------
 2 files changed, 60 insertions(+), 111 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index ad15c16f9b..87e8f5679b 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -76,6 +76,25 @@ clz             100100 ..... ..... 00000 000 1110 0000  @typea0
 cmp             000101 ..... ..... ..... 000 0000 0001  @typea
 cmpu            000101 ..... ..... ..... 000 0000 0011  @typea
 
+fadd            010110 ..... ..... ..... 0000 000 0000  @typea
+frsub           010110 ..... ..... ..... 0001 000 0000  @typea
+fmul            010110 ..... ..... ..... 0010 000 0000  @typea
+fdiv            010110 ..... ..... ..... 0011 000 0000  @typea
+fcmp_un         010110 ..... ..... ..... 0100 000 0000  @typea
+fcmp_lt         010110 ..... ..... ..... 0100 001 0000  @typea
+fcmp_eq         010110 ..... ..... ..... 0100 010 0000  @typea
+fcmp_le         010110 ..... ..... ..... 0100 011 0000  @typea
+fcmp_gt         010110 ..... ..... ..... 0100 100 0000  @typea
+fcmp_ne         010110 ..... ..... ..... 0100 101 0000  @typea
+fcmp_ge         010110 ..... ..... ..... 0100 110 0000  @typea
+
+# Note that flt and fint, unlike fsqrt, are documented as having the RB
+# operand which is unused.  So allow the field to be non-zero but discard
+# the value and treat as 2-operand insns.
+flt             010110 ..... ..... ----- 0101 000 0000  @typea0
+fint            010110 ..... ..... ----- 0110 000 0000  @typea0
+fsqrt           010110 ..... ..... 00000 0111 000 0000  @typea0
+
 idiv            010010 ..... ..... ..... 000 0000 0000  @typea
 idivu           010010 ..... ..... ..... 000 0000 0010  @typea
 
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 54de136a16..72541905ec 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -318,6 +318,14 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
     static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
     { return do_typeb_val(dc, a, SE, FN); }
 
+#define ENV_WRAPPER2(NAME, HELPER) \
+    static void NAME(TCGv_i32 out, TCGv_i32 ina) \
+    { HELPER(out, cpu_env, ina); }
+
+#define ENV_WRAPPER3(NAME, HELPER) \
+    static void NAME(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb) \
+    { HELPER(out, cpu_env, ina, inb); }
+
 /* No input carry, but output carry. */
 static void gen_add(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
@@ -464,6 +472,39 @@ static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 DO_TYPEA(cmp, false, gen_cmp)
 DO_TYPEA(cmpu, false, gen_cmpu)
 
+ENV_WRAPPER3(gen_fadd, gen_helper_fadd)
+ENV_WRAPPER3(gen_frsub, gen_helper_frsub)
+ENV_WRAPPER3(gen_fmul, gen_helper_fmul)
+ENV_WRAPPER3(gen_fdiv, gen_helper_fdiv)
+ENV_WRAPPER3(gen_fcmp_un, gen_helper_fcmp_un)
+ENV_WRAPPER3(gen_fcmp_lt, gen_helper_fcmp_lt)
+ENV_WRAPPER3(gen_fcmp_eq, gen_helper_fcmp_eq)
+ENV_WRAPPER3(gen_fcmp_le, gen_helper_fcmp_le)
+ENV_WRAPPER3(gen_fcmp_gt, gen_helper_fcmp_gt)
+ENV_WRAPPER3(gen_fcmp_ne, gen_helper_fcmp_ne)
+ENV_WRAPPER3(gen_fcmp_ge, gen_helper_fcmp_ge)
+
+DO_TYPEA_CFG(fadd, use_fpu, true, gen_fadd)
+DO_TYPEA_CFG(frsub, use_fpu, true, gen_frsub)
+DO_TYPEA_CFG(fmul, use_fpu, true, gen_fmul)
+DO_TYPEA_CFG(fdiv, use_fpu, true, gen_fdiv)
+DO_TYPEA_CFG(fcmp_un, use_fpu, true, gen_fcmp_un)
+DO_TYPEA_CFG(fcmp_lt, use_fpu, true, gen_fcmp_lt)
+DO_TYPEA_CFG(fcmp_eq, use_fpu, true, gen_fcmp_eq)
+DO_TYPEA_CFG(fcmp_le, use_fpu, true, gen_fcmp_le)
+DO_TYPEA_CFG(fcmp_gt, use_fpu, true, gen_fcmp_gt)
+DO_TYPEA_CFG(fcmp_ne, use_fpu, true, gen_fcmp_ne)
+DO_TYPEA_CFG(fcmp_ge, use_fpu, true, gen_fcmp_ge)
+
+ENV_WRAPPER2(gen_flt, gen_helper_flt)
+ENV_WRAPPER2(gen_fint, gen_helper_fint)
+ENV_WRAPPER2(gen_fsqrt, gen_helper_fsqrt)
+
+DO_TYPEA0_CFG(flt, use_fpu >= 2, true, gen_flt)
+DO_TYPEA0_CFG(fint, use_fpu >= 2, true, gen_fint)
+DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)
+
+/* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
 static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
 {
     gen_helper_divs(out, cpu_env, inb, ina);
@@ -1403,116 +1444,6 @@ static void dec_rts(DisasContext *dc)
     tcg_gen_add_i32(cpu_btarget, cpu_R[dc->ra], *dec_alu_op_b(dc));
 }
 
-static int dec_check_fpuv2(DisasContext *dc)
-{
-    if ((dc->cpu->cfg.use_fpu != 2) && (dc->tb_flags & MSR_EE_FLAG)) {
-        gen_raise_hw_excp(dc, ESR_EC_FPU);
-    }
-    return (dc->cpu->cfg.use_fpu == 2) ? PVR2_USE_FPU2_MASK : 0;
-}
-
-static void dec_fpu(DisasContext *dc)
-{
-    unsigned int fpu_insn;
-
-    if (trap_illegal(dc, !dc->cpu->cfg.use_fpu)) {
-        return;
-    }
-
-    fpu_insn = (dc->ir >> 7) & 7;
-
-    switch (fpu_insn) {
-        case 0:
-            gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
-                            cpu_R[dc->rb]);
-            break;
-
-        case 1:
-            gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
-                             cpu_R[dc->rb]);
-            break;
-
-        case 2:
-            gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
-                            cpu_R[dc->rb]);
-            break;
-
-        case 3:
-            gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
-                            cpu_R[dc->rb]);
-            break;
-
-        case 4:
-            switch ((dc->ir >> 4) & 7) {
-                case 0:
-                    gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                case 1:
-                    gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                case 2:
-                    gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                case 3:
-                    gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                case 4:
-                    gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                case 5:
-                    gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                case 6:
-                    gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
-                                       cpu_R[dc->ra], cpu_R[dc->rb]);
-                    break;
-                default:
-                    qemu_log_mask(LOG_UNIMP,
-                                  "unimplemented fcmp fpu_insn=%x pc=%x"
-                                  " opc=%x\n",
-                                  fpu_insn, (uint32_t)dc->base.pc_next,
-                                  dc->opcode);
-                    dc->abort_at_next_insn = 1;
-                    break;
-            }
-            break;
-
-        case 5:
-            if (!dec_check_fpuv2(dc)) {
-                return;
-            }
-            gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
-            break;
-
-        case 6:
-            if (!dec_check_fpuv2(dc)) {
-                return;
-            }
-            gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
-            break;
-
-        case 7:
-            if (!dec_check_fpuv2(dc)) {
-                return;
-            }
-            gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
-            break;
-
-        default:
-            qemu_log_mask(LOG_UNIMP, "unimplemented FPU insn fpu_insn=%x pc=%x"
-                          " opc=%x\n",
-                          fpu_insn, (uint32_t)dc->base.pc_next, dc->opcode);
-            dc->abort_at_next_insn = 1;
-            break;
-    }
-}
-
 static void dec_null(DisasContext *dc)
 {
     if (trap_illegal(dc, true)) {
@@ -1565,7 +1496,6 @@ static struct decoder_info {
     {DEC_BR, dec_br},
     {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
-    {DEC_FPU, dec_fpu},
     {DEC_MSR, dec_msr},
     {DEC_STREAM, dec_stream},
     {{0, 0}, dec_null}
-- 
2.25.1



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

* [PATCH v2 48/76] target/microblaze: Fix cpu unwind for fpu exceptions
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (46 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 47/76] target/microblaze: Convert dec_fpu " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG Richard Henderson
                   ` (28 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Restore the correct PC when an exception must be raised.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/op_helper.c | 37 +++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index d99d98051a..2c59d4492d 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -104,13 +104,16 @@ uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
 }
 
 /* raise FPU exception.  */
-static void raise_fpu_exception(CPUMBState *env)
+static void raise_fpu_exception(CPUMBState *env, uintptr_t ra)
 {
+    CPUState *cs = env_cpu(env);
+
     env->esr = ESR_EC_FPU;
-    helper_raise_exception(env, EXCP_HW_EXCP);
+    cs->exception_index = EXCP_HW_EXCP;
+    cpu_loop_exit_restore(cs, ra);
 }
 
-static void update_fpu_flags(CPUMBState *env, int flags)
+static void update_fpu_flags(CPUMBState *env, int flags, uintptr_t ra)
 {
     int raise = 0;
 
@@ -133,7 +136,7 @@ static void update_fpu_flags(CPUMBState *env, int flags)
     if (raise
         && (env->pvr.regs[2] & PVR2_FPU_EXC_MASK)
         && (env->msr & MSR_EE)) {
-        raise_fpu_exception(env);
+        raise_fpu_exception(env, ra);
     }
 }
 
@@ -148,7 +151,7 @@ uint32_t helper_fadd(CPUMBState *env, uint32_t a, uint32_t b)
     fd.f = float32_add(fa.f, fb.f, &env->fp_status);
 
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags);
+    update_fpu_flags(env, flags, GETPC());
     return fd.l;
 }
 
@@ -162,7 +165,7 @@ uint32_t helper_frsub(CPUMBState *env, uint32_t a, uint32_t b)
     fb.l = b;
     fd.f = float32_sub(fb.f, fa.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags);
+    update_fpu_flags(env, flags, GETPC());
     return fd.l;
 }
 
@@ -176,7 +179,7 @@ uint32_t helper_fmul(CPUMBState *env, uint32_t a, uint32_t b)
     fb.l = b;
     fd.f = float32_mul(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags);
+    update_fpu_flags(env, flags, GETPC());
 
     return fd.l;
 }
@@ -191,7 +194,7 @@ uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t b)
     fb.l = b;
     fd.f = float32_div(fb.f, fa.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags);
+    update_fpu_flags(env, flags, GETPC());
 
     return fd.l;
 }
@@ -206,7 +209,7 @@ uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b)
 
     if (float32_is_signaling_nan(fa.f, &env->fp_status) ||
         float32_is_signaling_nan(fb.f, &env->fp_status)) {
-        update_fpu_flags(env, float_flag_invalid);
+        update_fpu_flags(env, float_flag_invalid, GETPC());
         r = 1;
     }
 
@@ -229,7 +232,7 @@ uint32_t helper_fcmp_lt(CPUMBState *env, uint32_t a, uint32_t b)
     fb.l = b;
     r = float32_lt(fb.f, fa.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags & float_flag_invalid);
+    update_fpu_flags(env, flags & float_flag_invalid, GETPC());
 
     return r;
 }
@@ -245,7 +248,7 @@ uint32_t helper_fcmp_eq(CPUMBState *env, uint32_t a, uint32_t b)
     fb.l = b;
     r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags & float_flag_invalid);
+    update_fpu_flags(env, flags & float_flag_invalid, GETPC());
 
     return r;
 }
@@ -261,7 +264,7 @@ uint32_t helper_fcmp_le(CPUMBState *env, uint32_t a, uint32_t b)
     set_float_exception_flags(0, &env->fp_status);
     r = float32_le(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags & float_flag_invalid);
+    update_fpu_flags(env, flags & float_flag_invalid, GETPC());
 
 
     return r;
@@ -277,7 +280,7 @@ uint32_t helper_fcmp_gt(CPUMBState *env, uint32_t a, uint32_t b)
     set_float_exception_flags(0, &env->fp_status);
     r = float32_lt(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags & float_flag_invalid);
+    update_fpu_flags(env, flags & float_flag_invalid, GETPC());
     return r;
 }
 
@@ -291,7 +294,7 @@ uint32_t helper_fcmp_ne(CPUMBState *env, uint32_t a, uint32_t b)
     set_float_exception_flags(0, &env->fp_status);
     r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags & float_flag_invalid);
+    update_fpu_flags(env, flags & float_flag_invalid, GETPC());
 
     return r;
 }
@@ -306,7 +309,7 @@ uint32_t helper_fcmp_ge(CPUMBState *env, uint32_t a, uint32_t b)
     set_float_exception_flags(0, &env->fp_status);
     r = !float32_lt(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags & float_flag_invalid);
+    update_fpu_flags(env, flags & float_flag_invalid, GETPC());
 
     return r;
 }
@@ -330,7 +333,7 @@ uint32_t helper_fint(CPUMBState *env, uint32_t a)
     fa.l = a;
     r = float32_to_int32(fa.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags);
+    update_fpu_flags(env, flags, GETPC());
 
     return r;
 }
@@ -344,7 +347,7 @@ uint32_t helper_fsqrt(CPUMBState *env, uint32_t a)
     fa.l = a;
     fd.l = float32_sqrt(fa.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
-    update_fpu_flags(env, flags);
+    update_fpu_flags(env, flags, GETPC());
 
     return fd.l;
 }
-- 
2.25.1



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

* [PATCH v2 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (47 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 48/76] target/microblaze: Fix cpu unwind for fpu exceptions Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
                   ` (27 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Now that FSR is no longer a tcg global temp, we can say that
the fpu helpers do not write to tcg temps.  All temps are
read implicitly by the fpu exception path.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 79e1e8ecc7..64816c89e1 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -3,21 +3,21 @@ DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, i32)
 DEF_HELPER_FLAGS_3(divs, TCG_CALL_NO_WG, i32, env, i32, i32)
 DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
 
-DEF_HELPER_3(fadd, i32, env, i32, i32)
-DEF_HELPER_3(frsub, i32, env, i32, i32)
-DEF_HELPER_3(fmul, i32, env, i32, i32)
-DEF_HELPER_3(fdiv, i32, env, i32, i32)
-DEF_HELPER_2(flt, i32, env, i32)
-DEF_HELPER_2(fint, i32, env, i32)
-DEF_HELPER_2(fsqrt, i32, env, i32)
+DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(frsub, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_2(flt, TCG_CALL_NO_WG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fint, TCG_CALL_NO_WG, i32, env, i32)
+DEF_HELPER_FLAGS_2(fsqrt, TCG_CALL_NO_WG, i32, env, i32)
 
-DEF_HELPER_3(fcmp_un, i32, env, i32, i32)
-DEF_HELPER_3(fcmp_lt, i32, env, i32, i32)
-DEF_HELPER_3(fcmp_eq, i32, env, i32, i32)
-DEF_HELPER_3(fcmp_le, i32, env, i32, i32)
-DEF_HELPER_3(fcmp_gt, i32, env, i32, i32)
-DEF_HELPER_3(fcmp_ne, i32, env, i32, i32)
-DEF_HELPER_3(fcmp_ge, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_un, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_lt, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_eq, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_le, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_gt, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_ne, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(fcmp_ge, TCG_CALL_NO_WG, i32, env, i32, i32)
 
 DEF_HELPER_FLAGS_2(pcmpbf, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 #if !defined(CONFIG_USER_ONLY)
-- 
2.25.1



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

* [PATCH v2 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (48 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-31 21:09   ` Philippe Mathieu-Daudé
  2020-08-28 14:19 ` [PATCH v2 51/76] target/microblaze: Cache mem_index in DisasContext Richard Henderson
                   ` (26 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

There's no reason to define MSR_EE_FLAG; we can just use the
original MSR_EE define.  Document the other flags copied into
tb_flags with iflag to reserve those bits.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       | 4 +++-
 target/microblaze/translate.c | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 013858b8e0..594501e4e7 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -254,7 +254,9 @@ struct CPUMBState {
 
     /* Internal flags.  */
 #define IMM_FLAG	4
-#define MSR_EE_FLAG     (1 << 8)
+/* MSR_EE               (1 << 8)  */
+/* MSR_UM               (1 << 11) */
+/* MSR_VM               (1 << 13) */
 #define DRTI_FLAG	(1 << 16)
 #define DRTE_FLAG	(1 << 17)
 #define DRTB_FLAG	(1 << 18)
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 72541905ec..1f6731e0af 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -162,7 +162,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
  */
 static bool trap_illegal(DisasContext *dc, bool cond)
 {
-    if (cond && (dc->tb_flags & MSR_EE_FLAG)
+    if (cond && (dc->tb_flags & MSR_EE)
         && dc->cpu->cfg.illegal_opcode_exception) {
         gen_raise_hw_excp(dc, ESR_EC_ILLEGAL_OP);
     }
@@ -178,7 +178,7 @@ static bool trap_userspace(DisasContext *dc, bool cond)
     int mem_index = cpu_mmu_index(&dc->cpu->env, false);
     bool cond_user = cond && mem_index == MMU_USER_IDX;
 
-    if (cond_user && (dc->tb_flags & MSR_EE_FLAG)) {
+    if (cond_user && (dc->tb_flags & MSR_EE)) {
         gen_raise_hw_excp(dc, ESR_EC_PRIVINSN);
     }
     return cond_user;
-- 
2.25.1



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

* [PATCH v2 51/76] target/microblaze: Cache mem_index in DisasContext
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (49 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 52/76] target/microblaze: Fix cpu unwind for stackprot Richard Henderson
                   ` (25 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Ideally, nothing outside the top-level of translation even
has access to env.  Cache the value in init_disas_context.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 1f6731e0af..a55e110171 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -73,6 +73,7 @@ typedef struct DisasContext {
     unsigned int delayed_branch;
     unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
     unsigned int clear_imm;
+    int mem_index;
 
 #define JMP_NOJMP     0
 #define JMP_DIRECT    1
@@ -175,8 +176,7 @@ static bool trap_illegal(DisasContext *dc, bool cond)
  */
 static bool trap_userspace(DisasContext *dc, bool cond)
 {
-    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
-    bool cond_user = cond && mem_index == MMU_USER_IDX;
+    bool cond_user = cond && dc->mem_index == MMU_USER_IDX;
 
     if (cond_user && (dc->tb_flags & MSR_EE)) {
         gen_raise_hw_excp(dc, ESR_EC_PRIVINSN);
@@ -968,7 +968,7 @@ static void dec_load(DisasContext *dc)
     TCGv addr;
     unsigned int size;
     bool rev = false, ex = false, ea = false;
-    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
+    int mem_index = dc->mem_index;
     MemOp mop;
 
     mop = dc->opcode & 3;
@@ -1077,7 +1077,7 @@ static void dec_store(DisasContext *dc)
     TCGLabel *swx_skip = NULL;
     unsigned int size;
     bool rev = false, ex = false, ea = false;
-    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
+    int mem_index = dc->mem_index;
     MemOp mop;
 
     mop = dc->opcode & 3;
@@ -1540,6 +1540,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->ext_imm = dc->base.tb->cs_base;
     dc->r0 = NULL;
     dc->r0_set = false;
+    dc->mem_index = cpu_mmu_index(&cpu->env, false);
 
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
     dc->base.max_insns = MIN(dc->base.max_insns, bound);
-- 
2.25.1



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

* [PATCH v2 52/76] target/microblaze: Fix cpu unwind for stackprot
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (50 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 51/76] target/microblaze: Cache mem_index in DisasContext Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 53/76] target/microblaze: Convert dec_load and dec_store to decodetree Richard Henderson
                   ` (24 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Restore the correct PC when an exception must be raised.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h    | 2 +-
 target/microblaze/op_helper.c | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 64816c89e1..a473c1867b 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -26,7 +26,7 @@ DEF_HELPER_4(mmu_write, void, env, i32, i32, i32)
 #endif
 
 DEF_HELPER_5(memalign, void, env, tl, i32, i32, i32)
-DEF_HELPER_2(stackprot, void, env, tl)
+DEF_HELPER_FLAGS_2(stackprot, TCG_CALL_NO_WG, void, env, tl)
 
 DEF_HELPER_2(get, i32, i32, i32)
 DEF_HELPER_3(put, void, i32, i32, i32)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 2c59d4492d..a99c467364 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -389,12 +389,16 @@ void helper_memalign(CPUMBState *env, target_ulong addr,
 void helper_stackprot(CPUMBState *env, target_ulong addr)
 {
     if (addr < env->slr || addr > env->shr) {
+        CPUState *cs = env_cpu(env);
+
         qemu_log_mask(CPU_LOG_INT, "Stack protector violation at "
                       TARGET_FMT_lx " %x %x\n",
                       addr, env->slr, env->shr);
+
         env->ear = addr;
         env->esr = ESR_EC_STACKPROT;
-        helper_raise_exception(env, EXCP_HW_EXCP);
+        cs->exception_index = EXCP_HW_EXCP;
+        cpu_loop_exit_restore(cs, GETPC());
     }
 }
 
-- 
2.25.1



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

* [PATCH v2 53/76] target/microblaze: Convert dec_load and dec_store to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (51 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 52/76] target/microblaze: Fix cpu unwind for stackprot Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 54/76] target/microblaze: Assert no overlap in flags making up tb_flags Richard Henderson
                   ` (23 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  32 ++
 target/microblaze/translate.c  | 723 +++++++++++++++++++--------------
 2 files changed, 456 insertions(+), 299 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 87e8f5679b..47b92b9cbc 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -100,6 +100,22 @@ idivu           010010 ..... ..... ..... 000 0000 0010  @typea
 
 imm             101100 00000 00000 imm:16
 
+lbu             110000 ..... ..... ..... 0000 000 0000  @typea
+lbur            110000 ..... ..... ..... 0100 000 0000  @typea
+lbuea           110000 ..... ..... ..... 0001 000 0000  @typea
+lbui            111000 ..... ..... ................     @typeb
+
+lhu             110001 ..... ..... ..... 0000 000 0000  @typea
+lhur            110001 ..... ..... ..... 0100 000 0000  @typea
+lhuea           110001 ..... ..... ..... 0001 000 0000  @typea
+lhui            111001 ..... ..... ................     @typeb
+
+lw              110010 ..... ..... ..... 0000 000 0000  @typea
+lwr             110010 ..... ..... ..... 0100 000 0000  @typea
+lwea            110010 ..... ..... ..... 0001 000 0000  @typea
+lwx             110010 ..... ..... ..... 1000 000 0000  @typea
+lwi             111010 ..... ..... ................     @typeb
+
 mul             010000 ..... ..... ..... 000 0000 0000  @typea
 mulh            010000 ..... ..... ..... 000 0000 0001  @typea
 mulhu           010000 ..... ..... ..... 000 0000 0011  @typea
@@ -123,6 +139,22 @@ rsubic          001011 ..... ..... ................     @typeb
 rsubik          001101 ..... ..... ................     @typeb
 rsubikc         001111 ..... ..... ................     @typeb
 
+sb              110100 ..... ..... ..... 0000 000 0000  @typea
+sbr             110100 ..... ..... ..... 0100 000 0000  @typea
+sbea            110100 ..... ..... ..... 0001 000 0000  @typea
+sbi             111100 ..... ..... ................     @typeb
+
+sh              110101 ..... ..... ..... 0000 000 0000  @typea
+shr             110101 ..... ..... ..... 0100 000 0000  @typea
+shea            110101 ..... ..... ..... 0001 000 0000  @typea
+shi             111101 ..... ..... ................     @typeb
+
+sw              110110 ..... ..... ..... 0000 000 0000  @typea
+swr             110110 ..... ..... ..... 0100 000 0000  @typea
+swea            110110 ..... ..... ..... 0001 000 0000  @typea
+swx             110110 ..... ..... ..... 1000 000 0000  @typea
+swi             111110 ..... ..... ................     @typeb
+
 sext8           100100 ..... ..... 00000 000 0110 0000  @typea0
 sext16          100100 ..... ..... 00000 000 0110 0001  @typea0
 
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a55e110171..d2baa7db0e 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -105,6 +105,17 @@ static inline void t_sync_flags(DisasContext *dc)
     }
 }
 
+static inline void sync_jmpstate(DisasContext *dc)
+{
+    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
+        if (dc->jmp == JMP_DIRECT) {
+            tcg_gen_movi_i32(cpu_btaken, 1);
+        }
+        dc->jmp = JMP_INDIRECT;
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
+    }
+}
+
 static void gen_raise_exception(DisasContext *dc, uint32_t index)
 {
     TCGv_i32 tmp = tcg_const_i32(index);
@@ -668,6 +679,419 @@ static bool trans_wdic(DisasContext *dc, arg_wdic *a)
 DO_TYPEA(xor, false, tcg_gen_xor_i32)
 DO_TYPEBI(xori, false, tcg_gen_xori_i32)
 
+static TCGv compute_ldst_addr_typea(DisasContext *dc, int ra, int rb)
+{
+    TCGv ret = tcg_temp_new();
+
+    /* If any of the regs is r0, set t to the value of the other reg.  */
+    if (ra && rb) {
+        TCGv_i32 tmp = tcg_temp_new_i32();
+        tcg_gen_add_i32(tmp, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_extu_i32_tl(ret, tmp);
+        tcg_temp_free_i32(tmp);
+    } else if (ra) {
+        tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
+    } else if (rb) {
+        tcg_gen_extu_i32_tl(ret, cpu_R[rb]);
+    } else {
+        tcg_gen_movi_tl(ret, 0);
+    }
+
+    if ((ra == 1 || rb == 1) && dc->cpu->cfg.stackprot) {
+        gen_helper_stackprot(cpu_env, ret);
+    }
+    return ret;
+}
+
+static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
+{
+    TCGv ret = tcg_temp_new();
+
+    /* If any of the regs is r0, set t to the value of the other reg.  */
+    if (ra) {
+        TCGv_i32 tmp = tcg_temp_new_i32();
+        tcg_gen_addi_i32(tmp, cpu_R[ra], imm);
+        tcg_gen_extu_i32_tl(ret, tmp);
+        tcg_temp_free_i32(tmp);
+    } else {
+        tcg_gen_movi_tl(ret, (uint32_t)imm);
+    }
+
+    if (ra == 1 && dc->cpu->cfg.stackprot) {
+        gen_helper_stackprot(cpu_env, ret);
+    }
+    return ret;
+}
+
+static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
+{
+    int addr_size = dc->cpu->cfg.addr_size;
+    TCGv ret = tcg_temp_new();
+
+    if (addr_size == 32 || ra == 0) {
+        if (rb) {
+            tcg_gen_extu_i32_tl(ret, cpu_R[rb]);
+        } else {
+            tcg_gen_movi_tl(ret, 0);
+        }
+    } else {
+        if (rb) {
+            tcg_gen_concat_i32_i64(ret, cpu_R[rb], cpu_R[ra]);
+        } else {
+            tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
+            tcg_gen_shli_tl(ret, ret, 32);
+        }
+        if (addr_size < 64) {
+            /* Mask off out of range bits.  */
+            tcg_gen_andi_i64(ret, ret, MAKE_64BIT_MASK(0, addr_size));
+        }
+    }
+    return ret;
+}
+
+static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
+                    int mem_index, bool rev)
+{
+    TCGv_i32 v;
+    MemOp size = mop & MO_SIZE;
+
+    /*
+     * When doing reverse accesses we need to do two things.
+     *
+     * 1. Reverse the address wrt endianness.
+     * 2. Byteswap the data lanes on the way back into the CPU core.
+     */
+    if (rev) {
+        if (size > MO_8) {
+            mop ^= MO_BSWAP;
+        }
+        if (size < MO_32) {
+            tcg_gen_xori_tl(addr, addr, 3 - size);
+        }
+    }
+
+    t_sync_flags(dc);
+    sync_jmpstate(dc);
+
+    /*
+     * Microblaze gives MMU faults priority over faults due to
+     * unaligned addresses. That's why we speculatively do the load
+     * into v. If the load succeeds, we verify alignment of the
+     * address and if that succeeds we write into the destination reg.
+     */
+    v = tcg_temp_new_i32();
+    tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
+
+    /* TODO: Convert to CPUClass::do_unaligned_access.  */
+    if (dc->cpu->cfg.unaligned_exceptions && size > MO_8) {
+        TCGv_i32 t0 = tcg_const_i32(0);
+        TCGv_i32 treg = tcg_const_i32(rd);
+        TCGv_i32 tsize = tcg_const_i32((1 << size) - 1);
+
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
+        gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
+
+        tcg_temp_free_i32(t0);
+        tcg_temp_free_i32(treg);
+        tcg_temp_free_i32(tsize);
+    }
+
+    if (rd) {
+        tcg_gen_mov_i32(cpu_R[rd], v);
+    }
+
+    tcg_temp_free_i32(v);
+    tcg_temp_free(addr);
+    return true;
+}
+
+static bool trans_lbu(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
+}
+
+static bool trans_lbur(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, true);
+}
+
+static bool trans_lbuea(DisasContext *dc, arg_typea *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
+}
+
+static bool trans_lbui(DisasContext *dc, arg_typeb *arg)
+{
+    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
+    return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
+}
+
+static bool trans_lhu(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
+}
+
+static bool trans_lhur(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true);
+}
+
+static bool trans_lhuea(DisasContext *dc, arg_typea *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
+}
+
+static bool trans_lhui(DisasContext *dc, arg_typeb *arg)
+{
+    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
+    return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
+}
+
+static bool trans_lw(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
+}
+
+static bool trans_lwr(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true);
+}
+
+static bool trans_lwea(DisasContext *dc, arg_typea *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
+    return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
+}
+
+static bool trans_lwi(DisasContext *dc, arg_typeb *arg)
+{
+    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
+    return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
+}
+
+static bool trans_lwx(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+
+    /* lwx does not throw unaligned access errors, so force alignment */
+    tcg_gen_andi_tl(addr, addr, ~3);
+
+    t_sync_flags(dc);
+    sync_jmpstate(dc);
+
+    tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
+    tcg_gen_mov_tl(cpu_res_addr, addr);
+    tcg_temp_free(addr);
+
+    if (arg->rd) {
+        tcg_gen_mov_i32(cpu_R[arg->rd], cpu_res_val);
+    }
+
+    /* No support for AXI exclusive so always clear C */
+    tcg_gen_movi_i32(cpu_msr_c, 0);
+    return true;
+}
+
+static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
+                     int mem_index, bool rev)
+{
+    MemOp size = mop & MO_SIZE;
+
+    /*
+     * When doing reverse accesses we need to do two things.
+     *
+     * 1. Reverse the address wrt endianness.
+     * 2. Byteswap the data lanes on the way back into the CPU core.
+     */
+    if (rev) {
+        if (size > MO_8) {
+            mop ^= MO_BSWAP;
+        }
+        if (size < MO_32) {
+            tcg_gen_xori_tl(addr, addr, 3 - size);
+        }
+    }
+
+    t_sync_flags(dc);
+    sync_jmpstate(dc);
+
+    tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
+
+    /* TODO: Convert to CPUClass::do_unaligned_access.  */
+    if (dc->cpu->cfg.unaligned_exceptions && size > MO_8) {
+        TCGv_i32 t1 = tcg_const_i32(1);
+        TCGv_i32 treg = tcg_const_i32(rd);
+        TCGv_i32 tsize = tcg_const_i32((1 << size) - 1);
+
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
+        /* FIXME: if the alignment is wrong, we should restore the value
+         *        in memory. One possible way to achieve this is to probe
+         *        the MMU prior to the memaccess, thay way we could put
+         *        the alignment checks in between the probe and the mem
+         *        access.
+         */
+        gen_helper_memalign(cpu_env, addr, treg, t1, tsize);
+
+        tcg_temp_free_i32(t1);
+        tcg_temp_free_i32(treg);
+        tcg_temp_free_i32(tsize);
+    }
+
+    tcg_temp_free(addr);
+    return true;
+}
+
+static bool trans_sb(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
+}
+
+static bool trans_sbr(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, true);
+}
+
+static bool trans_sbea(DisasContext *dc, arg_typea *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
+}
+
+static bool trans_sbi(DisasContext *dc, arg_typeb *arg)
+{
+    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
+    return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
+}
+
+static bool trans_sh(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
+}
+
+static bool trans_shr(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true);
+}
+
+static bool trans_shea(DisasContext *dc, arg_typea *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
+}
+
+static bool trans_shi(DisasContext *dc, arg_typeb *arg)
+{
+    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
+    return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
+}
+
+static bool trans_sw(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
+}
+
+static bool trans_swr(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true);
+}
+
+static bool trans_swea(DisasContext *dc, arg_typea *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
+    return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
+}
+
+static bool trans_swi(DisasContext *dc, arg_typeb *arg)
+{
+    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
+    return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
+}
+
+static bool trans_swx(DisasContext *dc, arg_typea *arg)
+{
+    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
+    TCGLabel *swx_done = gen_new_label();
+    TCGLabel *swx_fail = gen_new_label();
+    TCGv_i32 tval;
+
+    t_sync_flags(dc);
+    sync_jmpstate(dc);
+
+    /* swx does not throw unaligned access errors, so force alignment */
+    tcg_gen_andi_tl(addr, addr, ~3);
+
+    /*
+     * Compare the address vs the one we used during lwx.
+     * On mismatch, the operation fails.  On match, addr dies at the
+     * branch, but we know we can use the equal version in the global.
+     * In either case, addr is no longer needed.
+     */
+    tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_fail);
+    tcg_temp_free(addr);
+
+    /*
+     * Compare the value loaded during lwx with current contents of
+     * the reserved location.
+     */
+    tval = tcg_temp_new_i32();
+
+    tcg_gen_atomic_cmpxchg_i32(tval, cpu_res_addr, cpu_res_val,
+                               reg_for_write(dc, arg->rd),
+                               dc->mem_index, MO_TEUL);
+
+    tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_fail);
+    tcg_temp_free_i32(tval);
+
+    /* Success */
+    tcg_gen_movi_i32(cpu_msr_c, 0);
+    tcg_gen_br(swx_done);
+
+    /* Failure */
+    gen_set_label(swx_fail);
+    tcg_gen_movi_i32(cpu_msr_c, 1);
+
+    gen_set_label(swx_done);
+
+    /*
+     * Prevent the saved address from working again without another ldx.
+     * Akin to the pseudocode setting reservation = 0.
+     */
+    tcg_gen_movi_tl(cpu_res_addr, -1);
+    return true;
+}
+
 static bool trans_zero(DisasContext *dc, arg_zero *arg)
 {
     /* If opcode_0_illegal, trap.  */
@@ -887,303 +1311,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-static inline void sync_jmpstate(DisasContext *dc)
-{
-    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
-        if (dc->jmp == JMP_DIRECT) {
-            tcg_gen_movi_i32(cpu_btaken, 1);
-        }
-        dc->jmp = JMP_INDIRECT;
-        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
-    }
-}
-
-static inline void compute_ldst_addr(DisasContext *dc, bool ea, TCGv t)
-{
-    /* Should be set to true if r1 is used by loadstores.  */
-    bool stackprot = false;
-    TCGv_i32 t32;
-
-    /* All load/stores use ra.  */
-    if (dc->ra == 1 && dc->cpu->cfg.stackprot) {
-        stackprot = true;
-    }
-
-    /* Treat the common cases first.  */
-    if (!dc->type_b) {
-        if (ea) {
-            int addr_size = dc->cpu->cfg.addr_size;
-
-            if (addr_size == 32) {
-                tcg_gen_extu_i32_tl(t, cpu_R[dc->rb]);
-                return;
-            }
-
-            tcg_gen_concat_i32_i64(t, cpu_R[dc->rb], cpu_R[dc->ra]);
-            if (addr_size < 64) {
-                /* Mask off out of range bits.  */
-                tcg_gen_andi_i64(t, t, MAKE_64BIT_MASK(0, addr_size));
-            }
-            return;
-        }
-
-        /* If any of the regs is r0, set t to the value of the other reg.  */
-        if (dc->ra == 0) {
-            tcg_gen_extu_i32_tl(t, cpu_R[dc->rb]);
-            return;
-        } else if (dc->rb == 0) {
-            tcg_gen_extu_i32_tl(t, cpu_R[dc->ra]);
-            return;
-        }
-
-        if (dc->rb == 1 && dc->cpu->cfg.stackprot) {
-            stackprot = true;
-        }
-
-        t32 = tcg_temp_new_i32();
-        tcg_gen_add_i32(t32, cpu_R[dc->ra], cpu_R[dc->rb]);
-        tcg_gen_extu_i32_tl(t, t32);
-        tcg_temp_free_i32(t32);
-
-        if (stackprot) {
-            gen_helper_stackprot(cpu_env, t);
-        }
-        return;
-    }
-    /* Immediate.  */
-    t32 = tcg_temp_new_i32();
-    tcg_gen_addi_i32(t32, cpu_R[dc->ra], dec_alu_typeb_imm(dc));
-    tcg_gen_extu_i32_tl(t, t32);
-    tcg_temp_free_i32(t32);
-
-    if (stackprot) {
-        gen_helper_stackprot(cpu_env, t);
-    }
-    return;
-}
-
-static void dec_load(DisasContext *dc)
-{
-    TCGv_i32 v;
-    TCGv addr;
-    unsigned int size;
-    bool rev = false, ex = false, ea = false;
-    int mem_index = dc->mem_index;
-    MemOp mop;
-
-    mop = dc->opcode & 3;
-    size = 1 << mop;
-    if (!dc->type_b) {
-        ea = extract32(dc->ir, 7, 1);
-        rev = extract32(dc->ir, 9, 1);
-        ex = extract32(dc->ir, 10, 1);
-    }
-    mop |= MO_TE;
-    if (rev) {
-        mop ^= MO_BSWAP;
-    }
-
-    if (trap_illegal(dc, size > 4)) {
-        return;
-    }
-
-    if (trap_userspace(dc, ea)) {
-        return;
-    }
-
-    t_sync_flags(dc);
-    addr = tcg_temp_new();
-    compute_ldst_addr(dc, ea, addr);
-    /* Extended addressing bypasses the MMU.  */
-    mem_index = ea ? MMU_NOMMU_IDX : mem_index;
-
-    /*
-     * When doing reverse accesses we need to do two things.
-     *
-     * 1. Reverse the address wrt endianness.
-     * 2. Byteswap the data lanes on the way back into the CPU core.
-     */
-    if (rev && size != 4) {
-        /* Endian reverse the address. t is addr.  */
-        switch (size) {
-            case 1:
-            {
-                tcg_gen_xori_tl(addr, addr, 3);
-                break;
-            }
-
-            case 2:
-                /* 00 -> 10
-                   10 -> 00.  */
-                tcg_gen_xori_tl(addr, addr, 2);
-                break;
-            default:
-                cpu_abort(CPU(dc->cpu), "Invalid reverse size\n");
-                break;
-        }
-    }
-
-    /* lwx does not throw unaligned access errors, so force alignment */
-    if (ex) {
-        tcg_gen_andi_tl(addr, addr, ~3);
-    }
-
-    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
-    sync_jmpstate(dc);
-
-    /* Verify alignment if needed.  */
-    /*
-     * Microblaze gives MMU faults priority over faults due to
-     * unaligned addresses. That's why we speculatively do the load
-     * into v. If the load succeeds, we verify alignment of the
-     * address and if that succeeds we write into the destination reg.
-     */
-    v = tcg_temp_new_i32();
-    tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
-
-    if (dc->cpu->cfg.unaligned_exceptions && size > 1) {
-        TCGv_i32 t0 = tcg_const_i32(0);
-        TCGv_i32 treg = tcg_const_i32(dc->rd);
-        TCGv_i32 tsize = tcg_const_i32(size - 1);
-
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
-        gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
-
-        tcg_temp_free_i32(t0);
-        tcg_temp_free_i32(treg);
-        tcg_temp_free_i32(tsize);
-    }
-
-    if (ex) {
-        tcg_gen_mov_tl(cpu_res_addr, addr);
-        tcg_gen_mov_i32(cpu_res_val, v);
-    }
-    if (dc->rd) {
-        tcg_gen_mov_i32(cpu_R[dc->rd], v);
-    }
-    tcg_temp_free_i32(v);
-
-    if (ex) { /* lwx */
-        /* no support for AXI exclusive so always clear C */
-        tcg_gen_movi_i32(cpu_msr_c, 0);
-    }
-
-    tcg_temp_free(addr);
-}
-
-static void dec_store(DisasContext *dc)
-{
-    TCGv addr;
-    TCGLabel *swx_skip = NULL;
-    unsigned int size;
-    bool rev = false, ex = false, ea = false;
-    int mem_index = dc->mem_index;
-    MemOp mop;
-
-    mop = dc->opcode & 3;
-    size = 1 << mop;
-    if (!dc->type_b) {
-        ea = extract32(dc->ir, 7, 1);
-        rev = extract32(dc->ir, 9, 1);
-        ex = extract32(dc->ir, 10, 1);
-    }
-    mop |= MO_TE;
-    if (rev) {
-        mop ^= MO_BSWAP;
-    }
-
-    if (trap_illegal(dc, size > 4)) {
-        return;
-    }
-
-    trap_userspace(dc, ea);
-
-    t_sync_flags(dc);
-    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
-    sync_jmpstate(dc);
-    /* SWX needs a temp_local.  */
-    addr = ex ? tcg_temp_local_new() : tcg_temp_new();
-    compute_ldst_addr(dc, ea, addr);
-    /* Extended addressing bypasses the MMU.  */
-    mem_index = ea ? MMU_NOMMU_IDX : mem_index;
-
-    if (ex) { /* swx */
-        TCGv_i32 tval;
-
-        /* swx does not throw unaligned access errors, so force alignment */
-        tcg_gen_andi_tl(addr, addr, ~3);
-
-        tcg_gen_movi_i32(cpu_msr_c, 1);
-        swx_skip = gen_new_label();
-        tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_skip);
-
-        /*
-         * Compare the value loaded at lwx with current contents of
-         * the reserved location.
-         */
-        tval = tcg_temp_new_i32();
-
-        tcg_gen_atomic_cmpxchg_i32(tval, addr, cpu_res_val,
-                                   cpu_R[dc->rd], mem_index,
-                                   mop);
-
-        tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_skip);
-        tcg_gen_movi_i32(cpu_msr_c, 0);
-        tcg_temp_free_i32(tval);
-    }
-
-    if (rev && size != 4) {
-        /* Endian reverse the address. t is addr.  */
-        switch (size) {
-            case 1:
-            {
-                tcg_gen_xori_tl(addr, addr, 3);
-                break;
-            }
-
-            case 2:
-                /* 00 -> 10
-                   10 -> 00.  */
-                /* Force addr into the temp.  */
-                tcg_gen_xori_tl(addr, addr, 2);
-                break;
-            default:
-                cpu_abort(CPU(dc->cpu), "Invalid reverse size\n");
-                break;
-        }
-    }
-
-    if (!ex) {
-        tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr, mem_index, mop);
-    }
-
-    /* Verify alignment if needed.  */
-    if (dc->cpu->cfg.unaligned_exceptions && size > 1) {
-        TCGv_i32 t1 = tcg_const_i32(1);
-        TCGv_i32 treg = tcg_const_i32(dc->rd);
-        TCGv_i32 tsize = tcg_const_i32(size - 1);
-
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
-        /* FIXME: if the alignment is wrong, we should restore the value
-         *        in memory. One possible way to achieve this is to probe
-         *        the MMU prior to the memaccess, thay way we could put
-         *        the alignment checks in between the probe and the mem
-         *        access.
-         */
-        gen_helper_memalign(cpu_env, addr, treg, t1, tsize);
-
-        tcg_temp_free_i32(t1);
-        tcg_temp_free_i32(treg);
-        tcg_temp_free_i32(tsize);
-    }
-
-    if (ex) {
-        gen_set_label(swx_skip);
-    }
-
-    tcg_temp_free(addr);
-}
-
 static inline void eval_cc(DisasContext *dc, unsigned int cc,
                            TCGv_i32 d, TCGv_i32 a)
 {
@@ -1491,8 +1618,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_LD, dec_load},
-    {DEC_ST, dec_store},
     {DEC_BR, dec_br},
     {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
-- 
2.25.1



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

* [PATCH v2 54/76] target/microblaze: Assert no overlap in flags making up tb_flags
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (52 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 53/76] target/microblaze: Convert dec_load and dec_store to decodetree Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 55/76] target/microblaze: Move bimm to BIMM_FLAG Richard Henderson
                   ` (22 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Create MSR_TB_MASK.  Use it in cpu_get_tb_cpu_state, and check
that IFLAGS_TB_MASK does not overlap.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 594501e4e7..2fc7cf26f1 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -261,8 +261,11 @@ struct CPUMBState {
 #define DRTE_FLAG	(1 << 17)
 #define DRTB_FLAG	(1 << 18)
 #define D_FLAG		(1 << 19)  /* Bit in ESR.  */
+
 /* TB dependent CPUMBState.  */
 #define IFLAGS_TB_MASK  (D_FLAG | IMM_FLAG | DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)
+#define MSR_TB_MASK     (MSR_UM | MSR_VM | MSR_EE)
+
     uint32_t iflags;
 
 #if !defined(CONFIG_USER_ONLY)
@@ -372,12 +375,14 @@ typedef MicroBlazeCPU ArchCPU;
 
 #include "exec/cpu-all.h"
 
+/* Ensure there is no overlap between the two masks. */
+QEMU_BUILD_BUG_ON(MSR_TB_MASK & IFLAGS_TB_MASK);
+
 static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
     *pc = env->pc;
-    *flags = (env->iflags & IFLAGS_TB_MASK) |
-             (env->msr & (MSR_UM | MSR_VM | MSR_EE));
+    *flags = (env->iflags & IFLAGS_TB_MASK) | (env->msr & MSR_TB_MASK);
     *cs_base = (*flags & IMM_FLAG ? env->imm : 0);
 }
 
-- 
2.25.1



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

* [PATCH v2 55/76] target/microblaze: Move bimm to BIMM_FLAG
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (53 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 54/76] target/microblaze: Assert no overlap in flags making up tb_flags Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed Richard Henderson
                   ` (21 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

It makes sense to keep BIMM with D_FLAG, as they can be written
back to iflags at the same time.  BIMM_FLAG does not need to be
added to IFLAGS_TB_MASK because it does not affect the next TB,
only the exception path out of the current TB.  Renumber IMM_FLAG,
as the value 4 holds no particular significance; pack these two
flags at the bottom of the bitfield.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  4 ++--
 target/microblaze/helper.c    |  2 +-
 target/microblaze/translate.c | 12 +++++-------
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 2fc7cf26f1..a5df1fa28f 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -231,7 +231,6 @@ typedef struct CPUMBState CPUMBState;
 struct CPUMBState {
     uint32_t btaken;
     uint32_t btarget;
-    uint32_t bimm;
 
     uint32_t imm;
     uint32_t regs[32];
@@ -253,7 +252,8 @@ struct CPUMBState {
     uint32_t res_val;
 
     /* Internal flags.  */
-#define IMM_FLAG	4
+#define IMM_FLAG        (1 << 0)
+#define BIMM_FLAG       (1 << 1)
 /* MSR_EE               (1 << 8)  */
 /* MSR_UM               (1 << 11) */
 /* MSR_VM               (1 << 13) */
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index f8e2ca12a9..06f4322e09 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -166,7 +166,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                 /* Reexecute the branch.  */
                 env->regs[17] -= 4;
                 /* was the branch immprefixed?.  */
-                if (env->bimm) {
+                if (env->iflags & BIMM_FLAG) {
                     env->regs[17] -= 4;
                     log_cpu_state_mask(CPU_LOG_INT, cs, 0);
                 }
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index d2baa7db0e..97a436c8d5 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1351,13 +1351,11 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i32 pc_true, TCGv_i32 pc_false)
 
 static void dec_setup_dslot(DisasContext *dc)
 {
-        TCGv_i32 tmp = tcg_const_i32(dc->type_b && (dc->tb_flags & IMM_FLAG));
-
-        dc->delayed_branch = 2;
-        dc->tb_flags |= D_FLAG;
-
-        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, bimm));
-        tcg_temp_free_i32(tmp);
+    dc->delayed_branch = 2;
+    dc->tb_flags |= D_FLAG;
+    if (dc->type_b && (dc->tb_flags & IMM_FLAG)) {
+        dc->tb_flags |= BIMM_FLAG;
+    }
 }
 
 static void dec_bcc(DisasContext *dc)
-- 
2.25.1



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

* [PATCH v2 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (54 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 55/76] target/microblaze: Move bimm to BIMM_FLAG Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 57/76] target/microblaze: Store "current" iflags in insn_start Richard Henderson
                   ` (20 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias, Edgar E . Iglesias

Do not call cpu_restore_state when no exception will be
delivered.  This can lead to inconsistent cpu state.

Reported-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/op_helper.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index a99c467364..e6dcc79243 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -419,32 +419,33 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
                                int mmu_idx, MemTxAttrs attrs,
                                MemTxResult response, uintptr_t retaddr)
 {
-    MicroBlazeCPU *cpu;
-    CPUMBState *env;
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
+
     qemu_log_mask(CPU_LOG_INT, "Transaction failed: vaddr 0x%" VADDR_PRIx
                   " physaddr 0x" TARGET_FMT_plx " size %d access type %s\n",
                   addr, physaddr, size,
                   access_type == MMU_INST_FETCH ? "INST_FETCH" :
                   (access_type == MMU_DATA_LOAD ? "DATA_LOAD" : "DATA_STORE"));
-    cpu = MICROBLAZE_CPU(cs);
-    env = &cpu->env;
 
-    cpu_restore_state(cs, retaddr, true);
     if (!(env->msr & MSR_EE)) {
         return;
     }
 
-    env->ear = addr;
     if (access_type == MMU_INST_FETCH) {
-        if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
-            env->esr = ESR_EC_INSN_BUS;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+        if (!cpu->cfg.iopb_bus_exception) {
+            return;
         }
+        env->esr = ESR_EC_INSN_BUS;
     } else {
-        if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
-            env->esr = ESR_EC_DATA_BUS;
-            helper_raise_exception(env, EXCP_HW_EXCP);
+        if (!cpu->cfg.dopb_bus_exception) {
+            return;
         }
+        env->esr = ESR_EC_DATA_BUS;
     }
+
+    env->ear = addr;
+    cs->exception_index = EXCP_HW_EXCP;
+    cpu_loop_exit_restore(cs, retaddr);
 }
 #endif
-- 
2.25.1



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

* [PATCH v2 57/76] target/microblaze: Store "current" iflags in insn_start
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (55 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 58/76] tcg: Add tcg_get_insn_start_param Richard Henderson
                   ` (19 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This data is available during exception unwinding, thus
we can restore it from there directly, rather than saving
it during the TB.  Thus we may remove the t_sync_flags()
calls in the load/store operations.

Note that these calls were missing from the other places
where runtime exceptions may be raised, such as idiv and
the floating point operations.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |  2 ++
 target/microblaze/translate.c | 24 +++++++++++++-----------
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index a5df1fa28f..83fadd36a5 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -228,6 +228,8 @@ typedef struct CPUMBState CPUMBState;
 #define STREAM_CONTROL   (1 << 3)
 #define STREAM_NONBLOCK  (1 << 4)
 
+#define TARGET_INSN_START_EXTRA_WORDS 1
+
 struct CPUMBState {
     uint32_t btaken;
     uint32_t btarget;
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 97a436c8d5..d2ee163294 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -58,6 +58,9 @@ typedef struct DisasContext {
     DisasContextBase base;
     MicroBlazeCPU *cpu;
 
+    /* TCG op of the current insn_start.  */
+    TCGOp *insn_start;
+
     TCGv_i32 r0;
     bool r0_set;
 
@@ -71,7 +74,7 @@ typedef struct DisasContext {
 
     unsigned int cpustate_changed;
     unsigned int delayed_branch;
-    unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
+    unsigned int tb_flags;
     unsigned int clear_imm;
     int mem_index;
 
@@ -96,12 +99,11 @@ static int typeb_imm(DisasContext *dc, int x)
 /* Include the auto-generated decoder.  */
 #include "decode-insns.c.inc"
 
-static inline void t_sync_flags(DisasContext *dc)
+static void t_sync_flags(DisasContext *dc)
 {
     /* Synch the tb dependent flags between translator and runtime.  */
-    if (dc->tb_flags != dc->synced_flags) {
-        tcg_gen_movi_i32(cpu_iflags, dc->tb_flags);
-        dc->synced_flags = dc->tb_flags;
+    if ((dc->tb_flags ^ dc->base.tb->flags) & ~MSR_TB_MASK) {
+        tcg_gen_movi_i32(cpu_iflags, dc->tb_flags & ~MSR_TB_MASK);
     }
 }
 
@@ -770,7 +772,6 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
         }
     }
 
-    t_sync_flags(dc);
     sync_jmpstate(dc);
 
     /*
@@ -893,7 +894,6 @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg)
     /* lwx does not throw unaligned access errors, so force alignment */
     tcg_gen_andi_tl(addr, addr, ~3);
 
-    t_sync_flags(dc);
     sync_jmpstate(dc);
 
     tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
@@ -929,7 +929,6 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
         }
     }
 
-    t_sync_flags(dc);
     sync_jmpstate(dc);
 
     tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
@@ -1046,7 +1045,6 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
     TCGLabel *swx_fail = gen_new_label();
     TCGv_i32 tval;
 
-    t_sync_flags(dc);
     sync_jmpstate(dc);
 
     /* swx does not throw unaligned access errors, so force alignment */
@@ -1655,7 +1653,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     int bound;
 
     dc->cpu = cpu;
-    dc->synced_flags = dc->tb_flags = dc->base.tb->flags;
+    dc->tb_flags = dc->base.tb->flags;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
     dc->jmp = dc->delayed_branch ? JMP_INDIRECT : JMP_NOJMP;
     dc->cpustate_changed = 0;
@@ -1675,7 +1673,10 @@ static void mb_tr_tb_start(DisasContextBase *dcb, CPUState *cs)
 
 static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
 {
-    tcg_gen_insn_start(dcb->pc_next);
+    DisasContext *dc = container_of(dcb, DisasContext, base);
+
+    tcg_gen_insn_start(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
+    dc->insn_start = tcg_last_op();
 }
 
 static bool mb_tr_breakpoint_check(DisasContextBase *dcb, CPUState *cs,
@@ -1917,4 +1918,5 @@ void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
     env->pc = data[0];
+    env->iflags = data[1];
 }
-- 
2.25.1



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

* [PATCH v2 58/76] tcg: Add tcg_get_insn_start_param
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (56 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 57/76] target/microblaze: Store "current" iflags in insn_start Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 59/76] target/microblaze: Use cc->do_unaligned_access Richard Henderson
                   ` (18 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

MicroBlaze will shortly need to update a parameter in place.
Add an interface to read to match that for write.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/tcg/tcg.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index d40c925d04..15da46131b 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -777,11 +777,26 @@ static inline TCGv_i32 TCGV_HIGH(TCGv_i64 t)
 }
 #endif
 
+static inline TCGArg tcg_get_insn_param(TCGOp *op, int arg)
+{
+    return op->args[arg];
+}
+
 static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v)
 {
     op->args[arg] = v;
 }
 
+static inline target_ulong tcg_get_insn_start_param(TCGOp *op, int arg)
+{
+#if TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
+    return tcg_get_insn_param(op, arg);
+#else
+    return tcg_get_insn_param(op, arg * 2) |
+           (tcg_get_insn_param(op, arg * 2 + 1) << 32);
+#endif
+}
+
 static inline void tcg_set_insn_start_param(TCGOp *op, int arg, target_ulong v)
 {
 #if TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
-- 
2.25.1



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

* [PATCH v2 59/76] target/microblaze: Use cc->do_unaligned_access
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (57 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 58/76] tcg: Add tcg_get_insn_start_param Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set Richard Henderson
                   ` (17 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This fixes the problem in which unaligned stores succeeded,
but then we raised the exception after modifying memory.
Store the ESS for the unaligned data access in the iflags
for the insn, so that it can be found during unwind.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       | 10 ++++-
 target/microblaze/helper.h    |  1 -
 target/microblaze/cpu.c       |  1 +
 target/microblaze/helper.c    | 28 ++++++++++++++
 target/microblaze/op_helper.c | 21 ----------
 target/microblaze/translate.c | 72 +++++++++++++----------------------
 6 files changed, 64 insertions(+), 69 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 83fadd36a5..63b8d93d41 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -79,10 +79,13 @@ typedef struct CPUMBState CPUMBState;
 
 /* Exception State Register (ESR) Fields */
 #define          ESR_DIZ       (1<<11) /* Zone Protection */
+#define          ESR_W         (1<<11) /* Unaligned word access */
 #define          ESR_S         (1<<10) /* Store instruction */
 
 #define          ESR_ESS_FSL_OFFSET     5
 
+#define          ESR_ESS_MASK  (0x7f << 5)
+
 #define          ESR_EC_FSL             0
 #define          ESR_EC_UNALIGNED_DATA  1
 #define          ESR_EC_ILLEGAL_OP      2
@@ -256,9 +259,11 @@ struct CPUMBState {
     /* Internal flags.  */
 #define IMM_FLAG        (1 << 0)
 #define BIMM_FLAG       (1 << 1)
-/* MSR_EE               (1 << 8)  */
+#define ESR_ESS_FLAG    (1 << 2)  /* indicates ESR_ESS_MASK is present */
+/* MSR_EE               (1 << 8)  -- these 3 are not in iflags but tb_flags */
 /* MSR_UM               (1 << 11) */
 /* MSR_VM               (1 << 13) */
+/* ESR_ESS_MASK         [11:5]    -- unwind into iflags for unaligned excp */
 #define DRTI_FLAG	(1 << 16)
 #define DRTE_FLAG	(1 << 17)
 #define DRTB_FLAG	(1 << 18)
@@ -330,6 +335,9 @@ struct MicroBlazeCPU {
 
 void mb_cpu_do_interrupt(CPUState *cs);
 bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
+void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+                                MMUAccessType access_type,
+                                int mmu_idx, uintptr_t retaddr);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index a473c1867b..3980fba797 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -25,7 +25,6 @@ DEF_HELPER_3(mmu_read, i32, env, i32, i32)
 DEF_HELPER_4(mmu_write, void, env, i32, i32, i32)
 #endif
 
-DEF_HELPER_5(memalign, void, env, tl, i32, i32, i32)
 DEF_HELPER_FLAGS_2(stackprot, TCG_CALL_NO_WG, void, env, tl)
 
 DEF_HELPER_2(get, i32, i32, i32)
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 1eabf5cc3f..67017ecc33 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -317,6 +317,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = mb_cpu_class_by_name;
     cc->has_work = mb_cpu_has_work;
     cc->do_interrupt = mb_cpu_do_interrupt;
+    cc->do_unaligned_access = mb_cpu_do_unaligned_access;
     cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
     cc->dump_state = mb_cpu_dump_state;
     cc->set_pc = mb_cpu_set_pc;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 06f4322e09..0e3be251a7 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -296,3 +296,31 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
     }
     return false;
 }
+
+void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+                                MMUAccessType access_type,
+                                int mmu_idx, uintptr_t retaddr)
+{
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    uint32_t esr, iflags;
+
+    /* Recover the pc and iflags from the corresponding insn_start.  */
+    cpu_restore_state(cs, retaddr, true);
+    iflags = cpu->env.iflags;
+
+    qemu_log_mask(CPU_LOG_INT,
+                  "Unaligned access addr=" TARGET_FMT_lx
+                  " pc=%x iflags=%x\n", addr, cpu->env.pc, iflags);
+
+    esr = ESR_EC_UNALIGNED_DATA;
+    if (likely(iflags & ESR_ESS_FLAG)) {
+        esr |= iflags & ESR_ESS_MASK;
+    } else {
+        qemu_log_mask(LOG_UNIMP, "Unaligned access without ESR_ESS_FLAG\n");
+    }
+
+    cpu->env.ear = addr;
+    cpu->env.esr = esr;
+    cs->exception_index = EXCP_HW_EXCP;
+    cpu_loop_exit(cs);
+}
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index e6dcc79243..4614e99db3 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -365,27 +365,6 @@ uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
     return 0;
 }
 
-void helper_memalign(CPUMBState *env, target_ulong addr,
-                     uint32_t dr, uint32_t wr,
-                     uint32_t mask)
-{
-    if (addr & mask) {
-            qemu_log_mask(CPU_LOG_INT,
-                          "unaligned access addr=" TARGET_FMT_lx
-                          " mask=%x, wr=%d dr=r%d\n",
-                          addr, mask, wr, dr);
-            env->ear = addr;
-            env->esr = ESR_EC_UNALIGNED_DATA | (wr << 10) | (dr & 31) << 5;
-            if (mask == 3) {
-                env->esr |= 1 << 11;
-            }
-            if (!(env->msr & MSR_EE)) {
-                return;
-            }
-            helper_raise_exception(env, EXCP_HW_EXCP);
-    }
-}
-
 void helper_stackprot(CPUMBState *env, target_ulong addr)
 {
     if (addr < env->slr || addr > env->shr) {
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index d2ee163294..597b96ffb3 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -751,10 +751,22 @@ static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
     return ret;
 }
 
+static void record_unaligned_ess(DisasContext *dc, int rd,
+                                 MemOp size, bool store)
+{
+    uint32_t iflags = tcg_get_insn_start_param(dc->insn_start, 1);
+
+    iflags |= ESR_ESS_FLAG;
+    iflags |= rd << 5;
+    iflags |= store * ESR_S;
+    iflags |= (size == MO_32) * ESR_W;
+
+    tcg_set_insn_start_param(dc->insn_start, 1, iflags);
+}
+
 static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
                     int mem_index, bool rev)
 {
-    TCGv_i32 v;
     MemOp size = mop & MO_SIZE;
 
     /*
@@ -774,34 +786,15 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
 
     sync_jmpstate(dc);
 
-    /*
-     * Microblaze gives MMU faults priority over faults due to
-     * unaligned addresses. That's why we speculatively do the load
-     * into v. If the load succeeds, we verify alignment of the
-     * address and if that succeeds we write into the destination reg.
-     */
-    v = tcg_temp_new_i32();
-    tcg_gen_qemu_ld_i32(v, addr, mem_index, mop);
-
-    /* TODO: Convert to CPUClass::do_unaligned_access.  */
-    if (dc->cpu->cfg.unaligned_exceptions && size > MO_8) {
-        TCGv_i32 t0 = tcg_const_i32(0);
-        TCGv_i32 treg = tcg_const_i32(rd);
-        TCGv_i32 tsize = tcg_const_i32((1 << size) - 1);
-
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
-        gen_helper_memalign(cpu_env, addr, treg, t0, tsize);
-
-        tcg_temp_free_i32(t0);
-        tcg_temp_free_i32(treg);
-        tcg_temp_free_i32(tsize);
+    if (size > MO_8 &&
+        (dc->tb_flags & MSR_EE) &&
+        dc->cpu->cfg.unaligned_exceptions) {
+        record_unaligned_ess(dc, rd, size, false);
+        mop |= MO_ALIGN;
     }
 
-    if (rd) {
-        tcg_gen_mov_i32(cpu_R[rd], v);
-    }
+    tcg_gen_qemu_ld_i32(reg_for_write(dc, rd), addr, mem_index, mop);
 
-    tcg_temp_free_i32(v);
     tcg_temp_free(addr);
     return true;
 }
@@ -931,28 +924,15 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
 
     sync_jmpstate(dc);
 
-    tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
-
-    /* TODO: Convert to CPUClass::do_unaligned_access.  */
-    if (dc->cpu->cfg.unaligned_exceptions && size > MO_8) {
-        TCGv_i32 t1 = tcg_const_i32(1);
-        TCGv_i32 treg = tcg_const_i32(rd);
-        TCGv_i32 tsize = tcg_const_i32((1 << size) - 1);
-
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
-        /* FIXME: if the alignment is wrong, we should restore the value
-         *        in memory. One possible way to achieve this is to probe
-         *        the MMU prior to the memaccess, thay way we could put
-         *        the alignment checks in between the probe and the mem
-         *        access.
-         */
-        gen_helper_memalign(cpu_env, addr, treg, t1, tsize);
-
-        tcg_temp_free_i32(t1);
-        tcg_temp_free_i32(treg);
-        tcg_temp_free_i32(tsize);
+    if (size > MO_8 &&
+        (dc->tb_flags & MSR_EE) &&
+        dc->cpu->cfg.unaligned_exceptions) {
+        record_unaligned_ess(dc, rd, size, true);
+        mop |= MO_ALIGN;
     }
 
+    tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
+
     tcg_temp_free(addr);
     return true;
 }
-- 
2.25.1



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

* [PATCH v2 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (58 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 59/76] target/microblaze: Use cc->do_unaligned_access Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 61/76] target/microblaze: Replace delayed_branch " Richard Henderson
                   ` (16 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

This more general update variable will be able to handle
delay slots as well.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 597b96ffb3..c0b586f467 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -75,7 +75,7 @@ typedef struct DisasContext {
     unsigned int cpustate_changed;
     unsigned int delayed_branch;
     unsigned int tb_flags;
-    unsigned int clear_imm;
+    unsigned int tb_flags_to_set;
     int mem_index;
 
 #define JMP_NOJMP     0
@@ -535,8 +535,7 @@ static bool trans_imm(DisasContext *dc, arg_imm *arg)
 {
     dc->ext_imm = arg->imm << 16;
     tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
-    dc->tb_flags |= IMM_FLAG;
-    dc->clear_imm = 0;
+    dc->tb_flags_to_set = IMM_FLAG;
     return true;
 }
 
@@ -1688,7 +1687,8 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
                   (uint32_t)dc->base.pc_next);
     }
 
-    dc->clear_imm = 1;
+    dc->tb_flags_to_set = 0;
+
     ir = cpu_ldl_code(env, dc->base.pc_next);
     if (!decode(dc, ir)) {
         old_decode(dc, ir);
@@ -1700,10 +1700,13 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
         dc->r0_set = false;
     }
 
-    if (dc->clear_imm && (dc->tb_flags & IMM_FLAG)) {
-        dc->tb_flags &= ~IMM_FLAG;
+    /* Discard the imm global when its contents cannot be used. */
+    if ((dc->tb_flags & ~dc->tb_flags_to_set) & IMM_FLAG) {
         tcg_gen_discard_i32(cpu_imm);
     }
+
+    dc->tb_flags &= ~IMM_FLAG;
+    dc->tb_flags |= dc->tb_flags_to_set;
     dc->base.pc_next += 4;
 
     if (dc->delayed_branch && --dc->delayed_branch == 0) {
-- 
2.25.1



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

* [PATCH v2 61/76] target/microblaze: Replace delayed_branch with tb_flags_to_set
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (59 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
                   ` (15 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The multi-stage counter can be replaced by clearing D_FLAG,
the or'ing in tb_flags_to_set.  The jump then happens when
D_FLAG is finally cleared.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index c0b586f467..811c92d23b 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -73,7 +73,6 @@ typedef struct DisasContext {
     uint16_t imm;
 
     unsigned int cpustate_changed;
-    unsigned int delayed_branch;
     unsigned int tb_flags;
     unsigned int tb_flags_to_set;
     int mem_index;
@@ -1328,10 +1327,9 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i32 pc_true, TCGv_i32 pc_false)
 
 static void dec_setup_dslot(DisasContext *dc)
 {
-    dc->delayed_branch = 2;
-    dc->tb_flags |= D_FLAG;
+    dc->tb_flags_to_set |= D_FLAG;
     if (dc->type_b && (dc->tb_flags & IMM_FLAG)) {
-        dc->tb_flags |= BIMM_FLAG;
+        dc->tb_flags_to_set |= BIMM_FLAG;
     }
 }
 
@@ -1343,7 +1341,6 @@ static void dec_bcc(DisasContext *dc)
     cc = EXTRACT_FIELD(dc->ir, 21, 23);
     dslot = dc->ir & (1 << 25);
 
-    dc->delayed_branch = 1;
     if (dslot) {
         dec_setup_dslot(dc);
     }
@@ -1419,7 +1416,6 @@ static void dec_br(DisasContext *dc)
         }
     }
 
-    dc->delayed_branch = 1;
     if (dslot) {
         dec_setup_dslot(dc);
     }
@@ -1633,8 +1629,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
 
     dc->cpu = cpu;
     dc->tb_flags = dc->base.tb->flags;
-    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
-    dc->jmp = dc->delayed_branch ? JMP_INDIRECT : JMP_NOJMP;
+    dc->jmp = dc->tb_flags & D_FLAG ? JMP_INDIRECT : JMP_NOJMP;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
     dc->ext_imm = dc->base.tb->cs_base;
@@ -1705,11 +1700,11 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
         tcg_gen_discard_i32(cpu_imm);
     }
 
-    dc->tb_flags &= ~IMM_FLAG;
+    dc->tb_flags &= ~(IMM_FLAG | BIMM_FLAG | D_FLAG);
     dc->tb_flags |= dc->tb_flags_to_set;
     dc->base.pc_next += 4;
 
-    if (dc->delayed_branch && --dc->delayed_branch == 0) {
+    if (dc->jmp != JMP_NOJMP && !(dc->tb_flags & D_FLAG)) {
         if (dc->tb_flags & DRTI_FLAG) {
             do_rti(dc);
         }
@@ -1719,8 +1714,6 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
         if (dc->tb_flags & DRTE_FLAG) {
             do_rte(dc);
         }
-        /* Clear the delay slot flag.  */
-        dc->tb_flags &= ~D_FLAG;
         dc->base.is_jmp = DISAS_JUMP;
     }
 
-- 
2.25.1



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

* [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (60 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 61/76] target/microblaze: Replace delayed_branch " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-31 21:08   ` Philippe Mathieu-Daudé
  2020-08-28 14:19 ` [PATCH v2 63/76] target/microblaze: Convert brk and brki to decodetree Richard Henderson
                   ` (14 subsequent siblings)
  76 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Using lookup_symbol is quite slow; remove that.  Decode the
various bits of iflags; only show imm, btaken, btarget when
they are relevant to iflags.  Improve formatting.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/translate.c | 67 +++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 26 deletions(-)

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 811c92d23b..3b63fd79e5 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1818,41 +1818,56 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 {
     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
     CPUMBState *env = &cpu->env;
+    uint32_t iflags;
     int i;
 
-    if (!env) {
-        return;
-    }
-
-    qemu_fprintf(f, "IN: PC=%x %s\n",
-                 env->pc, lookup_symbol(env->pc));
-    qemu_fprintf(f, "rmsr=%x resr=%x rear=%" PRIx64 " "
-                 "imm=%x iflags=%x fsr=%x rbtr=%x\n",
-                 env->msr, env->esr, env->ear,
-                 env->imm, env->iflags, env->fsr, env->btr);
-    qemu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
-                 env->btaken, env->btarget,
+    qemu_fprintf(f, "pc=0x%08x msr=0x%05x mode=%s(saved=%s) eip=%d ie=%d\n",
+                 env->pc, env->msr,
                  (env->msr & MSR_UM) ? "user" : "kernel",
                  (env->msr & MSR_UMS) ? "user" : "kernel",
                  (bool)(env->msr & MSR_EIP),
                  (bool)(env->msr & MSR_IE));
-    for (i = 0; i < 12; i++) {
-        qemu_fprintf(f, "rpvr%2.2d=%8.8x ", i, env->pvr.regs[i]);
-        if ((i + 1) % 4 == 0) {
-            qemu_fprintf(f, "\n");
-        }
+
+    iflags = env->iflags;
+    qemu_fprintf(f, "iflags: 0x%08x", iflags);
+    if (iflags & IMM_FLAG) {
+        qemu_fprintf(f, " IMM(0x%08x)", env->imm);
+    }
+    if (iflags & BIMM_FLAG) {
+        qemu_fprintf(f, " BIMM");
+    }
+    if (iflags & D_FLAG) {
+        qemu_fprintf(f, " D(btaken=%d btarget=0x%08x)",
+                     env->btaken, env->btarget);
+    }
+    if (iflags & DRTI_FLAG) {
+        qemu_fprintf(f, " DRTI");
+    }
+    if (iflags & DRTE_FLAG) {
+        qemu_fprintf(f, " DRTE");
+    }
+    if (iflags & DRTB_FLAG) {
+        qemu_fprintf(f, " DRTB");
+    }
+    if (iflags & ESR_ESS_FLAG) {
+        qemu_fprintf(f, " ESR_ESS(0x%04x)", iflags & ESR_ESS_MASK);
+    }
+
+    qemu_fprintf(f, "\nesr=0x%04x fsr=0x%02x btr=0x%08x edr=0x%x\n"
+                 "ear=0x%016" PRIx64 " slr=0x%x shr=0x%x\n",
+                 env->esr, env->fsr, env->btr, env->edr,
+                 env->ear, env->slr, env->shr);
+
+    for (i = 0; i < 12; i++) {
+        qemu_fprintf(f, "rpvr%-2d=%08x%c",
+                     i, env->pvr.regs[i], i % 4 == 3 ? '\n' : ' ');
     }
 
-    /* Registers that aren't modeled are reported as 0 */
-    qemu_fprintf(f, "redr=%x rpid=0 rzpr=0 rtlbx=0 rtlbsx=0 "
-                    "rtlblo=0 rtlbhi=0\n", env->edr);
-    qemu_fprintf(f, "slr=%x shr=%x\n", env->slr, env->shr);
     for (i = 0; i < 32; i++) {
-        qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
-        if ((i + 1) % 4 == 0)
-            qemu_fprintf(f, "\n");
-        }
-    qemu_fprintf(f, "\n\n");
+        qemu_fprintf(f, "r%2.2d=%08x%c",
+                     i, env->regs[i], i % 4 == 3 ? '\n' : ' ');
+    }
+    qemu_fprintf(f, "\n");
 }
 
 void mb_tcg_init(void)
-- 
2.25.1



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

* [PATCH v2 63/76] target/microblaze: Convert brk and brki to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (61 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 64/76] target/microblaze: Convert mbar " Richard Henderson
                   ` (13 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Split these out of the normal branch instructions, as they require
special handling.  Perform the entire operation inline, instead of
raising EXCP_BREAK to do the work in mb_cpu_do_interrupt.

This fixes a bug in that brki rd, imm, for imm != 0x18 is not
supposed to set MSR_BIP.  This fixes a bug in that imm == 0 is
the reset vector and 0x18 is the debug vector, and neither should
raise a tcg exception in system mode.

Introduce EXCP_SYSCALL for microblaze-linux-user.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h          |   2 +-
 target/microblaze/insns.decode   |  11 ++++
 linux-user/microblaze/cpu_loop.c |   2 +-
 target/microblaze/helper.c       |  10 +--
 target/microblaze/translate.c    | 107 ++++++++++++++++++-------------
 5 files changed, 79 insertions(+), 53 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 63b8d93d41..1528749a0b 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -31,7 +31,7 @@ typedef struct CPUMBState CPUMBState;
 
 #define EXCP_MMU        1
 #define EXCP_IRQ        2
-#define EXCP_BREAK      3
+#define EXCP_SYSCALL    3  /* user-only */
 #define EXCP_HW_BREAK   4
 #define EXCP_HW_EXCP    5
 
diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 47b92b9cbc..9273a51d20 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -19,7 +19,9 @@
 
 &typea0         rd ra
 &typea          rd ra rb
+&typea_br       rd rb
 &typeb          rd ra imm
+&typeb_br       rd imm
 
 # Include any IMM prefix in the value reported.
 %extimm         0:s16 !function=typeb_imm
@@ -30,9 +32,15 @@
 # Officially typea, but with rb==0, which is not used.
 @typea0         ...... rd:5 ra:5 ................       &typea0
 
+# Officially typea, but with ra as opcode.
+@typea_br       ...... rd:5 ..... rb:5 ...........      &typea_br
+
 # Officially typeb, but any immediate extension is unused.
 @typeb_bs       ...... rd:5 ra:5 ..... ...... imm:5     &typeb
 
+# Officially typeb, but with ra as opcode.
+@typeb_br       ...... rd:5 ..... ................      &typeb_br imm=%extimm
+
 # For convenience, extract the two imm_w/imm_s fields, then pack
 # them back together as "imm".  Doing this makes it easiest to
 # match the required zero at bit 5.
@@ -60,6 +68,9 @@ andi            101001 ..... ..... ................     @typeb
 andn            100011 ..... ..... ..... 000 0000 0000  @typea
 andni           101011 ..... ..... ................     @typeb
 
+brk             100110 ..... 01100 ..... 000 0000 0000  @typea_br
+brki            101110 ..... 01100 ................     @typeb_br
+
 bsrl            010001 ..... ..... ..... 000 0000 0000  @typea
 bsra            010001 ..... ..... ..... 010 0000 0000  @typea
 bsll            010001 ..... ..... ..... 100 0000 0000  @typea
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 3de99ea311..c3396a6e09 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -48,7 +48,7 @@ void cpu_loop(CPUMBState *env)
         case EXCP_INTERRUPT:
           /* just indicate that signals should be handled asap */
           break;
-        case EXCP_BREAK:
+        case EXCP_SYSCALL:
             /* Return address is 4 bytes after the call.  */
             env->regs[14] += 4;
             env->pc = env->regs[14];
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 0e3be251a7..1667822fb7 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -230,7 +230,6 @@ void mb_cpu_do_interrupt(CPUState *cs)
             //log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             break;
 
-        case EXCP_BREAK:
         case EXCP_HW_BREAK:
             assert(!(env->iflags & IMM_FLAG));
             assert(!(env->iflags & D_FLAG));
@@ -242,13 +241,8 @@ void mb_cpu_do_interrupt(CPUState *cs)
             msr &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             msr |= t;
             msr |= MSR_BIP;
-            if (cs->exception_index == EXCP_HW_BREAK) {
-                env->regs[16] = env->pc;
-                msr |= MSR_BIP;
-                env->pc = cpu->cfg.base_vectors + 0x18;
-            } else {
-                env->pc = env->btarget;
-            }
+            env->regs[16] = env->pc;
+            env->pc = cpu->cfg.base_vectors + 0x18;
             mb_cpu_write_msr(env, msr);
             break;
         default:
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 3b63fd79e5..1c772b95d9 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1068,6 +1068,65 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
     return true;
 }
 
+static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
+{
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+    tcg_gen_mov_i32(cpu_pc, reg_for_read(dc, arg->rb));
+    if (arg->rd) {
+        tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
+    }
+    tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_BIP);
+    tcg_gen_movi_tl(cpu_res_addr, -1);
+
+    dc->base.is_jmp = DISAS_UPDATE;
+    return true;
+}
+
+static bool trans_brki(DisasContext *dc, arg_typeb_br *arg)
+{
+    uint32_t imm = arg->imm;
+
+    if (trap_userspace(dc, imm != 0x8 && imm != 0x18)) {
+        return true;
+    }
+    tcg_gen_movi_i32(cpu_pc, imm);
+    if (arg->rd) {
+        tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
+    }
+    tcg_gen_movi_tl(cpu_res_addr, -1);
+
+#ifdef CONFIG_USER_ONLY
+    switch (imm) {
+    case 0x8:  /* syscall trap */
+        gen_raise_exception_sync(dc, EXCP_SYSCALL);
+        break;
+    case 0x18: /* debug trap */
+        gen_raise_exception_sync(dc, EXCP_DEBUG);
+        break;
+    default:   /* eliminated with trap_userspace check */
+        g_assert_not_reached();
+    }
+#else
+    uint32_t msr_to_set = 0;
+
+    if (imm != 0x18) {
+        msr_to_set |= MSR_BIP;
+    }
+    if (imm == 0x8 || imm == 0x18) {
+        /* MSR_UM and MSR_VM are in tb_flags, so we know their value. */
+        msr_to_set |= (dc->tb_flags & (MSR_UM | MSR_VM)) << 1;
+        tcg_gen_andi_i32(cpu_msr, cpu_msr,
+                         ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM));
+    }
+    tcg_gen_ori_i32(cpu_msr, cpu_msr, msr_to_set);
+    dc->base.is_jmp = DISAS_UPDATE;
+#endif
+
+    return true;
+}
+
 static bool trans_zero(DisasContext *dc, arg_zero *arg)
 {
     /* If opcode_0_illegal, trap.  */
@@ -1359,6 +1418,7 @@ static void dec_bcc(DisasContext *dc)
 static void dec_br(DisasContext *dc)
 {
     unsigned int dslot, link, abs, mbar;
+    uint32_t add_pc;
 
     dslot = dc->ir & (1 << 20);
     abs = dc->ir & (1 << 19);
@@ -1401,21 +1461,6 @@ static void dec_br(DisasContext *dc)
         return;
     }
 
-    if (abs && link && !dslot) {
-        if (dc->type_b) {
-            /* BRKI */
-            uint32_t imm = dec_alu_typeb_imm(dc);
-            if (trap_userspace(dc, imm != 8 && imm != 0x18)) {
-                return;
-            }
-        } else {
-            /* BRK */
-            if (trap_userspace(dc, true)) {
-                return;
-            }
-        }
-    }
-
     if (dslot) {
         dec_setup_dslot(dc);
     }
@@ -1423,38 +1468,14 @@ static void dec_br(DisasContext *dc)
         tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
     }
 
-    if (abs) {
-        if (dc->type_b) {
-            uint32_t dest = dec_alu_typeb_imm(dc);
-
-            dc->jmp = JMP_DIRECT;
-            dc->jmp_pc = dest;
-            tcg_gen_movi_i32(cpu_btarget, dest);
-            if (link && !dslot) {
-                switch (dest) {
-                case 8:
-                case 0x18:
-                    gen_raise_exception_sync(dc, EXCP_BREAK);
-                    break;
-                case 0:
-                    gen_raise_exception_sync(dc, EXCP_DEBUG);
-                    break;
-                }
-            }
-        } else {
-            dc->jmp = JMP_INDIRECT;
-            tcg_gen_mov_i32(cpu_btarget, cpu_R[dc->rb]);
-            if (link && !dslot) {
-                gen_raise_exception_sync(dc, EXCP_BREAK);
-            }
-        }
-    } else if (dc->type_b) {
+    add_pc = abs ? 0 : dc->base.pc_next;
+    if (dc->type_b) {
         dc->jmp = JMP_DIRECT;
-        dc->jmp_pc = dc->base.pc_next + dec_alu_typeb_imm(dc);
+        dc->jmp_pc = add_pc + dec_alu_typeb_imm(dc);
         tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
     } else {
         dc->jmp = JMP_INDIRECT;
-        tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], dc->base.pc_next);
+        tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], add_pc);
     }
     tcg_gen_movi_i32(cpu_btaken, 1);
 }
-- 
2.25.1



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

* [PATCH v2 64/76] target/microblaze: Convert mbar to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (62 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 63/76] target/microblaze: Convert brk and brki to decodetree Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 65/76] target/microblaze: Reorganize branching Richard Henderson
                   ` (12 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Split this out of the normal branch instructions,
as it requires special handling.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  2 +
 target/microblaze/translate.c  | 85 +++++++++++++++++++---------------
 2 files changed, 49 insertions(+), 38 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 9273a51d20..8eba47d90c 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -127,6 +127,8 @@ lwea            110010 ..... ..... ..... 0001 000 0000  @typea
 lwx             110010 ..... ..... ..... 1000 000 0000  @typea
 lwi             111010 ..... ..... ................     @typeb
 
+mbar            101110 imm:5 00010 0000 0000 0000 0100
+
 mul             010000 ..... ..... ..... 000 0000 0000  @typea
 mulh            010000 ..... ..... ..... 000 0000 0001  @typea
 mulhu           010000 ..... ..... ..... 000 0000 0011  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 1c772b95d9..832cf85c64 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1127,6 +1127,52 @@ static bool trans_brki(DisasContext *dc, arg_typeb_br *arg)
     return true;
 }
 
+static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
+{
+    int mbar_imm = arg->imm;
+
+    /* Data access memory barrier.  */
+    if ((mbar_imm & 2) == 0) {
+        tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
+    }
+
+    /* Sleep. */
+    if (mbar_imm & 16) {
+        TCGv_i32 tmp_1;
+
+        if (trap_userspace(dc, true)) {
+            /* Sleep is a privileged instruction.  */
+            return true;
+        }
+
+        t_sync_flags(dc);
+
+        tmp_1 = tcg_const_i32(1);
+        tcg_gen_st_i32(tmp_1, cpu_env,
+                       -offsetof(MicroBlazeCPU, env)
+                       +offsetof(CPUState, halted));
+        tcg_temp_free_i32(tmp_1);
+
+        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
+
+        gen_raise_exception(dc, EXCP_HLT);
+    }
+
+    /*
+     * If !(mbar_imm & 1), this is an instruction access memory barrier
+     * and we need to end the TB so that we recognize self-modified
+     * code immediately.
+     *
+     * However, there are some data mbars that need the TB break
+     * (and return to main loop) to recognize interrupts right away.
+     * E.g. recognizing a change to an interrupt controller register.
+     *
+     * Therefore, choose to end the TB always.
+     */
+    dc->cpustate_changed = 1;
+    return true;
+}
+
 static bool trans_zero(DisasContext *dc, arg_zero *arg)
 {
     /* If opcode_0_illegal, trap.  */
@@ -1417,50 +1463,13 @@ static void dec_bcc(DisasContext *dc)
 
 static void dec_br(DisasContext *dc)
 {
-    unsigned int dslot, link, abs, mbar;
+    unsigned int dslot, link, abs;
     uint32_t add_pc;
 
     dslot = dc->ir & (1 << 20);
     abs = dc->ir & (1 << 19);
     link = dc->ir & (1 << 18);
 
-    /* Memory barrier.  */
-    mbar = (dc->ir >> 16) & 31;
-    if (mbar == 2 && dc->imm == 4) {
-        uint16_t mbar_imm = dc->rd;
-
-        /* Data access memory barrier.  */
-        if ((mbar_imm & 2) == 0) {
-            tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
-        }
-
-        /* mbar IMM & 16 decodes to sleep.  */
-        if (mbar_imm & 16) {
-            TCGv_i32 tmp_1;
-
-            if (trap_userspace(dc, true)) {
-                /* Sleep is a privileged instruction.  */
-                return;
-            }
-
-            t_sync_flags(dc);
-
-            tmp_1 = tcg_const_i32(1);
-            tcg_gen_st_i32(tmp_1, cpu_env,
-                           -offsetof(MicroBlazeCPU, env)
-                           +offsetof(CPUState, halted));
-            tcg_temp_free_i32(tmp_1);
-
-            tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
-
-            gen_raise_exception(dc, EXCP_HLT);
-            return;
-        }
-        /* Break the TB.  */
-        dc->cpustate_changed = 1;
-        return;
-    }
-
     if (dslot) {
         dec_setup_dslot(dc);
     }
-- 
2.25.1



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

* [PATCH v2 65/76] target/microblaze: Reorganize branching
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (63 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 64/76] target/microblaze: Convert mbar " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 66/76] target/microblaze: Convert dec_br to decodetree Richard Henderson
                   ` (11 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Remove the btaken variable, and simplify things by always computing
the full branch destination into btarget.  This avoids all need for
sync_jmpstate().

Retain the direct branch behaviour by remembering the jump destination
in jmp_dest, discarding btarget.  In the normal case, where the branch
delay slot cannot trap (e.g. arithmetic not memory operation), tcg will
remove the computation into btarget, leaving us with just the tcg
direct branching at the end.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu.h       |   4 +-
 target/microblaze/translate.c | 192 ++++++++++++++--------------------
 2 files changed, 79 insertions(+), 117 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 1528749a0b..4298f242a6 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -234,8 +234,8 @@ typedef struct CPUMBState CPUMBState;
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
 struct CPUMBState {
-    uint32_t btaken;
-    uint32_t btarget;
+    uint32_t bvalue;   /* TCG temporary, only valid during a TB */
+    uint32_t btarget;  /* Full resolved branch destination */
 
     uint32_t imm;
     uint32_t regs[32];
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 832cf85c64..1545974669 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -45,7 +45,7 @@ static TCGv_i32 cpu_pc;
 static TCGv_i32 cpu_msr;
 static TCGv_i32 cpu_msr_c;
 static TCGv_i32 cpu_imm;
-static TCGv_i32 cpu_btaken;
+static TCGv_i32 cpu_bvalue;
 static TCGv_i32 cpu_btarget;
 static TCGv_i32 cpu_iflags;
 static TCGv cpu_res_addr;
@@ -77,12 +77,11 @@ typedef struct DisasContext {
     unsigned int tb_flags_to_set;
     int mem_index;
 
-#define JMP_NOJMP     0
-#define JMP_DIRECT    1
-#define JMP_DIRECT_CC 2
-#define JMP_INDIRECT  3
-    unsigned int jmp;
-    uint32_t jmp_pc;
+    /* Condition under which to jump, including NEVER and ALWAYS. */
+    TCGCond jmp_cond;
+
+    /* Immediate branch-taken destination, or -1 for indirect. */
+    uint32_t jmp_dest;
 
     int abort_at_next_insn;
 } DisasContext;
@@ -106,17 +105,6 @@ static void t_sync_flags(DisasContext *dc)
     }
 }
 
-static inline void sync_jmpstate(DisasContext *dc)
-{
-    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
-        if (dc->jmp == JMP_DIRECT) {
-            tcg_gen_movi_i32(cpu_btaken, 1);
-        }
-        dc->jmp = JMP_INDIRECT;
-        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
-    }
-}
-
 static void gen_raise_exception(DisasContext *dc, uint32_t index)
 {
     TCGv_i32 tmp = tcg_const_i32(index);
@@ -782,8 +770,6 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
         }
     }
 
-    sync_jmpstate(dc);
-
     if (size > MO_8 &&
         (dc->tb_flags & MSR_EE) &&
         dc->cpu->cfg.unaligned_exceptions) {
@@ -885,8 +871,6 @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg)
     /* lwx does not throw unaligned access errors, so force alignment */
     tcg_gen_andi_tl(addr, addr, ~3);
 
-    sync_jmpstate(dc);
-
     tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
     tcg_gen_mov_tl(cpu_res_addr, addr);
     tcg_temp_free(addr);
@@ -920,8 +904,6 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
         }
     }
 
-    sync_jmpstate(dc);
-
     if (size > MO_8 &&
         (dc->tb_flags & MSR_EE) &&
         dc->cpu->cfg.unaligned_exceptions) {
@@ -1023,8 +1005,6 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
     TCGLabel *swx_fail = gen_new_label();
     TCGv_i32 tval;
 
-    sync_jmpstate(dc);
-
     /* swx does not throw unaligned access errors, so force alignment */
     tcg_gen_andi_tl(addr, addr, ~3);
 
@@ -1392,44 +1372,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-static inline void eval_cc(DisasContext *dc, unsigned int cc,
-                           TCGv_i32 d, TCGv_i32 a)
-{
-    static const int mb_to_tcg_cc[] = {
-        [CC_EQ] = TCG_COND_EQ,
-        [CC_NE] = TCG_COND_NE,
-        [CC_LT] = TCG_COND_LT,
-        [CC_LE] = TCG_COND_LE,
-        [CC_GE] = TCG_COND_GE,
-        [CC_GT] = TCG_COND_GT,
-    };
-
-    switch (cc) {
-    case CC_EQ:
-    case CC_NE:
-    case CC_LT:
-    case CC_LE:
-    case CC_GE:
-    case CC_GT:
-        tcg_gen_setcondi_i32(mb_to_tcg_cc[cc], d, a, 0);
-        break;
-    default:
-        cpu_abort(CPU(dc->cpu), "Unknown condition code %x.\n", cc);
-        break;
-    }
-}
-
-static void eval_cond_jmp(DisasContext *dc, TCGv_i32 pc_true, TCGv_i32 pc_false)
-{
-    TCGv_i32 zero = tcg_const_i32(0);
-
-    tcg_gen_movcond_i32(TCG_COND_NE, cpu_pc,
-                        cpu_btaken, zero,
-                        pc_true, pc_false);
-
-    tcg_temp_free_i32(zero);
-}
-
 static void dec_setup_dslot(DisasContext *dc)
 {
     dc->tb_flags_to_set |= D_FLAG;
@@ -1440,8 +1382,17 @@ static void dec_setup_dslot(DisasContext *dc)
 
 static void dec_bcc(DisasContext *dc)
 {
+    static const TCGCond mb_to_tcg_cc[] = {
+        [CC_EQ] = TCG_COND_EQ,
+        [CC_NE] = TCG_COND_NE,
+        [CC_LT] = TCG_COND_LT,
+        [CC_LE] = TCG_COND_LE,
+        [CC_GE] = TCG_COND_GE,
+        [CC_GT] = TCG_COND_GT,
+    };
     unsigned int cc;
     unsigned int dslot;
+    TCGv_i32 zero, next;
 
     cc = EXTRACT_FIELD(dc->ir, 21, 23);
     dslot = dc->ir & (1 << 25);
@@ -1450,15 +1401,29 @@ static void dec_bcc(DisasContext *dc)
         dec_setup_dslot(dc);
     }
 
+    dc->jmp_cond = mb_to_tcg_cc[cc];
+
+    /* Cache the condition register in cpu_bvalue across any delay slot.  */
+    tcg_gen_mov_i32(cpu_bvalue, cpu_R[dc->ra]);
+
+    /* Store the branch taken destination into btarget.  */
     if (dc->type_b) {
-        dc->jmp = JMP_DIRECT_CC;
-        dc->jmp_pc = dc->base.pc_next + dec_alu_typeb_imm(dc);
-        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
+        dc->jmp_dest = dc->base.pc_next + dec_alu_typeb_imm(dc);
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
     } else {
-        dc->jmp = JMP_INDIRECT;
-        tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], dc->base.pc_next);
+        dc->jmp_dest = -1;
+        tcg_gen_addi_i32(cpu_btarget, reg_for_read(dc, dc->rb),
+                         dc->base.pc_next);
     }
-    eval_cc(dc, cc, cpu_btaken, cpu_R[dc->ra]);
+
+    /* Compute the final destination into btarget.  */
+    zero = tcg_const_i32(0);
+    next = tcg_const_i32(dc->base.pc_next + (dslot + 1) * 4);
+    tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
+                        reg_for_read(dc, dc->ra), zero,
+                        cpu_btarget, next);
+    tcg_temp_free_i32(zero);
+    tcg_temp_free_i32(next);
 }
 
 static void dec_br(DisasContext *dc)
@@ -1479,14 +1444,13 @@ static void dec_br(DisasContext *dc)
 
     add_pc = abs ? 0 : dc->base.pc_next;
     if (dc->type_b) {
-        dc->jmp = JMP_DIRECT;
-        dc->jmp_pc = add_pc + dec_alu_typeb_imm(dc);
-        tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
+        dc->jmp_dest = add_pc + dec_alu_typeb_imm(dc);
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
     } else {
-        dc->jmp = JMP_INDIRECT;
+        dc->jmp_dest = -1;
         tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], add_pc);
     }
-    tcg_gen_movi_i32(cpu_btaken, 1);
+    dc->jmp_cond = TCG_COND_ALWAYS;
 }
 
 static inline void do_rti(DisasContext *dc)
@@ -1567,8 +1531,8 @@ static void dec_rts(DisasContext *dc)
         dc->tb_flags |= DRTE_FLAG;
     }
 
-    dc->jmp = JMP_INDIRECT;
-    tcg_gen_movi_i32(cpu_btaken, 1);
+    dc->jmp_cond = TCG_COND_ALWAYS;
+    dc->jmp_dest = -1;
     tcg_gen_add_i32(cpu_btarget, cpu_R[dc->ra], *dec_alu_op_b(dc));
 }
 
@@ -1659,13 +1623,14 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
 
     dc->cpu = cpu;
     dc->tb_flags = dc->base.tb->flags;
-    dc->jmp = dc->tb_flags & D_FLAG ? JMP_INDIRECT : JMP_NOJMP;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
     dc->ext_imm = dc->base.tb->cs_base;
     dc->r0 = NULL;
     dc->r0_set = false;
     dc->mem_index = cpu_mmu_index(&cpu->env, false);
+    dc->jmp_cond = dc->tb_flags & D_FLAG ? TCG_COND_ALWAYS : TCG_COND_NEVER;
+    dc->jmp_dest = -1;
 
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
     dc->base.max_insns = MIN(dc->base.max_insns, bound);
@@ -1734,14 +1699,12 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
     dc->tb_flags |= dc->tb_flags_to_set;
     dc->base.pc_next += 4;
 
-    if (dc->jmp != JMP_NOJMP && !(dc->tb_flags & D_FLAG)) {
+    if (dc->jmp_cond != TCG_COND_NEVER && !(dc->tb_flags & D_FLAG)) {
         if (dc->tb_flags & DRTI_FLAG) {
             do_rti(dc);
-        }
-        if (dc->tb_flags & DRTB_FLAG) {
+        } else if (dc->tb_flags & DRTB_FLAG) {
             do_rtb(dc);
-        }
-        if (dc->tb_flags & DRTE_FLAG) {
+        } else if (dc->tb_flags & DRTE_FLAG) {
             do_rte(dc);
         }
         dc->base.is_jmp = DISAS_JUMP;
@@ -1766,19 +1729,13 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
     }
 
     t_sync_flags(dc);
-    if (dc->tb_flags & D_FLAG) {
-        sync_jmpstate(dc);
-        dc->jmp = JMP_NOJMP;
-    }
 
     switch (dc->base.is_jmp) {
     case DISAS_TOO_MANY:
-        assert(dc->jmp == JMP_NOJMP);
         gen_goto_tb(dc, 0, dc->base.pc_next);
         return;
 
     case DISAS_UPDATE:
-        assert(dc->jmp == JMP_NOJMP);
         if (unlikely(cs->singlestep_enabled)) {
             gen_raise_exception(dc, EXCP_DEBUG);
         } else {
@@ -1787,35 +1744,41 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
         return;
 
     case DISAS_JUMP:
-        switch (dc->jmp) {
-        case JMP_INDIRECT:
-            {
-                TCGv_i32 tmp_pc = tcg_const_i32(dc->base.pc_next);
-                eval_cond_jmp(dc, cpu_btarget, tmp_pc);
-                tcg_temp_free_i32(tmp_pc);
+        if (dc->jmp_dest != -1 && !cs->singlestep_enabled) {
+            /* Direct jump. */
+            tcg_gen_discard_i32(cpu_btarget);
 
-                if (unlikely(cs->singlestep_enabled)) {
-                    gen_raise_exception(dc, EXCP_DEBUG);
-                } else {
-                    tcg_gen_exit_tb(NULL, 0);
-                }
-            }
-            return;
+            if (dc->jmp_cond != TCG_COND_ALWAYS) {
+                /* Conditional direct jump. */
+                TCGLabel *taken = gen_new_label();
+                TCGv_i32 tmp = tcg_temp_new_i32();
 
-        case JMP_DIRECT_CC:
-            {
-                TCGLabel *l1 = gen_new_label();
-                tcg_gen_brcondi_i32(TCG_COND_NE, cpu_btaken, 0, l1);
+                /*
+                 * Copy bvalue to a temp now, so we can discard bvalue.
+                 * This can avoid writing bvalue to memory when the
+                 * delay slot cannot raise an exception.
+                 */
+                tcg_gen_mov_i32(tmp, cpu_bvalue);
+                tcg_gen_discard_i32(cpu_bvalue);
+
+                tcg_gen_brcondi_i32(dc->jmp_cond, tmp, 0, taken);
                 gen_goto_tb(dc, 1, dc->base.pc_next);
-                gen_set_label(l1);
+                gen_set_label(taken);
             }
-            /* fall through */
-
-        case JMP_DIRECT:
-            gen_goto_tb(dc, 0, dc->jmp_pc);
+            gen_goto_tb(dc, 0, dc->jmp_dest);
             return;
         }
-        /* fall through */
+
+        /* Indirect jump (or direct jump w/ singlestep) */
+        tcg_gen_mov_i32(cpu_pc, cpu_btarget);
+        tcg_gen_discard_i32(cpu_btarget);
+
+        if (unlikely(cs->singlestep_enabled)) {
+            gen_raise_exception(dc, EXCP_DEBUG);
+        } else {
+            tcg_gen_exit_tb(NULL, 0);
+        }
+        return;
 
     default:
         g_assert_not_reached();
@@ -1867,8 +1830,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
         qemu_fprintf(f, " BIMM");
     }
     if (iflags & D_FLAG) {
-        qemu_fprintf(f, " D(btaken=%d btarget=0x%08x)",
-                     env->btaken, env->btarget);
+        qemu_fprintf(f, " D(btarget=0x%08x)", env->btarget);
     }
     if (iflags & DRTI_FLAG) {
         qemu_fprintf(f, " DRTI");
@@ -1918,7 +1880,7 @@ void mb_tcg_init(void)
         SP(msr_c),
         SP(imm),
         SP(iflags),
-        SP(btaken),
+        SP(bvalue),
         SP(btarget),
         SP(res_val),
     };
-- 
2.25.1



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

* [PATCH v2 66/76] target/microblaze: Convert dec_br to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (64 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 65/76] target/microblaze: Reorganize branching Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 67/76] target/microblaze: Convert dec_bcc " Richard Henderson
                   ` (10 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode | 14 ++++++
 target/microblaze/translate.c  | 87 +++++++++++++++++++---------------
 2 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 8eba47d90c..340dd999b6 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -68,6 +68,20 @@ andi            101001 ..... ..... ................     @typeb
 andn            100011 ..... ..... ..... 000 0000 0000  @typea
 andni           101011 ..... ..... ................     @typeb
 
+br              100110 ..... 00000 ..... 000 0000 0000  @typea_br
+bra             100110 ..... 01000 ..... 000 0000 0000  @typea_br
+brd             100110 ..... 10000 ..... 000 0000 0000  @typea_br
+brad            100110 ..... 11000 ..... 000 0000 0000  @typea_br
+brld            100110 ..... 10100 ..... 000 0000 0000  @typea_br
+brald           100110 ..... 11100 ..... 000 0000 0000  @typea_br
+
+bri             101110 ..... 00000 ................     @typeb_br
+brai            101110 ..... 01000 ................     @typeb_br
+brid            101110 ..... 10000 ................     @typeb_br
+braid           101110 ..... 11000 ................     @typeb_br
+brlid           101110 ..... 10100 ................     @typeb_br
+bralid          101110 ..... 11100 ................     @typeb_br
+
 brk             100110 ..... 01100 ..... 000 0000 0000  @typea_br
 brki            101110 ..... 01100 ................     @typeb_br
 
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 1545974669..5c6e6e599e 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1048,6 +1048,53 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
     return true;
 }
 
+static void setup_dslot(DisasContext *dc, bool type_b)
+{
+    dc->tb_flags_to_set |= D_FLAG;
+    if (type_b && (dc->tb_flags & IMM_FLAG)) {
+        dc->tb_flags_to_set |= BIMM_FLAG;
+    }
+}
+
+static bool do_branch(DisasContext *dc, int dest_rb, int dest_imm,
+                      bool delay, bool abs, int link)
+{
+    uint32_t add_pc;
+
+    if (delay) {
+        setup_dslot(dc, dest_rb < 0);
+    }
+
+    if (link) {
+        tcg_gen_movi_i32(cpu_R[link], dc->base.pc_next);
+    }
+
+    /* Store the branch taken destination into btarget.  */
+    add_pc = abs ? 0 : dc->base.pc_next;
+    if (dest_rb > 0) {
+        dc->jmp_dest = -1;
+        tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], add_pc);
+    } else {
+        dc->jmp_dest = add_pc + dest_imm;
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
+    }
+    dc->jmp_cond = TCG_COND_ALWAYS;
+    return true;
+}
+
+#define DO_BR(NAME, NAMEI, DELAY, ABS, LINK)                               \
+    static bool trans_##NAME(DisasContext *dc, arg_typea_br *arg)          \
+    { return do_branch(dc, arg->rb, 0, DELAY, ABS, LINK ? arg->rd : 0); }  \
+    static bool trans_##NAMEI(DisasContext *dc, arg_typeb_br *arg)         \
+    { return do_branch(dc, -1, arg->imm, DELAY, ABS, LINK ? arg->rd : 0); }
+
+DO_BR(br, bri, false, false, false)
+DO_BR(bra, brai, false, true, false)
+DO_BR(brd, brid, true, false, false)
+DO_BR(brad, braid, true, true, false)
+DO_BR(brld, brlid, true, false, true)
+DO_BR(brald, bralid, true, true, true)
+
 static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
 {
     if (trap_userspace(dc, true)) {
@@ -1372,14 +1419,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-static void dec_setup_dslot(DisasContext *dc)
-{
-    dc->tb_flags_to_set |= D_FLAG;
-    if (dc->type_b && (dc->tb_flags & IMM_FLAG)) {
-        dc->tb_flags_to_set |= BIMM_FLAG;
-    }
-}
-
 static void dec_bcc(DisasContext *dc)
 {
     static const TCGCond mb_to_tcg_cc[] = {
@@ -1398,7 +1437,7 @@ static void dec_bcc(DisasContext *dc)
     dslot = dc->ir & (1 << 25);
 
     if (dslot) {
-        dec_setup_dslot(dc);
+        setup_dslot(dc, dc->type_b);
     }
 
     dc->jmp_cond = mb_to_tcg_cc[cc];
@@ -1426,33 +1465,6 @@ static void dec_bcc(DisasContext *dc)
     tcg_temp_free_i32(next);
 }
 
-static void dec_br(DisasContext *dc)
-{
-    unsigned int dslot, link, abs;
-    uint32_t add_pc;
-
-    dslot = dc->ir & (1 << 20);
-    abs = dc->ir & (1 << 19);
-    link = dc->ir & (1 << 18);
-
-    if (dslot) {
-        dec_setup_dslot(dc);
-    }
-    if (link && dc->rd) {
-        tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
-    }
-
-    add_pc = abs ? 0 : dc->base.pc_next;
-    if (dc->type_b) {
-        dc->jmp_dest = add_pc + dec_alu_typeb_imm(dc);
-        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
-    } else {
-        dc->jmp_dest = -1;
-        tcg_gen_addi_i32(cpu_btarget, cpu_R[dc->rb], add_pc);
-    }
-    dc->jmp_cond = TCG_COND_ALWAYS;
-}
-
 static inline void do_rti(DisasContext *dc)
 {
     TCGv_i32 t0, t1;
@@ -1521,7 +1533,7 @@ static void dec_rts(DisasContext *dc)
         return;
     }
 
-    dec_setup_dslot(dc);
+    setup_dslot(dc, true);
 
     if (i_bit) {
         dc->tb_flags |= DRTI_FLAG;
@@ -1583,7 +1595,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_BR, dec_br},
     {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
     {DEC_MSR, dec_msr},
-- 
2.25.1



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

* [PATCH v2 67/76] target/microblaze: Convert dec_bcc to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (65 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 66/76] target/microblaze: Convert dec_br to decodetree Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 68/76] target/microblaze: Convert dec_rts " Richard Henderson
                   ` (9 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode | 36 +++++++++++++
 target/microblaze/translate.c  | 99 ++++++++++++++++++----------------
 2 files changed, 88 insertions(+), 47 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 340dd999b6..e6a61f147a 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -20,8 +20,10 @@
 &typea0         rd ra
 &typea          rd ra rb
 &typea_br       rd rb
+&typea_bc       ra rb
 &typeb          rd ra imm
 &typeb_br       rd imm
+&typeb_bc       ra imm
 
 # Include any IMM prefix in the value reported.
 %extimm         0:s16 !function=typeb_imm
@@ -35,12 +37,18 @@
 # Officially typea, but with ra as opcode.
 @typea_br       ...... rd:5 ..... rb:5 ...........      &typea_br
 
+# Officially typea, but with rd as opcode.
+@typea_bc       ...... ..... ra:5 rb:5 ...........      &typea_bc
+
 # Officially typeb, but any immediate extension is unused.
 @typeb_bs       ...... rd:5 ra:5 ..... ...... imm:5     &typeb
 
 # Officially typeb, but with ra as opcode.
 @typeb_br       ...... rd:5 ..... ................      &typeb_br imm=%extimm
 
+# Officially typeb, but with rd as opcode.
+@typeb_bc       ...... ..... ra:5 ................      &typeb_bc imm=%extimm
+
 # For convenience, extract the two imm_w/imm_s fields, then pack
 # them back together as "imm".  Doing this makes it easiest to
 # match the required zero at bit 5.
@@ -68,6 +76,34 @@ andi            101001 ..... ..... ................     @typeb
 andn            100011 ..... ..... ..... 000 0000 0000  @typea
 andni           101011 ..... ..... ................     @typeb
 
+beq             100111 00000 ..... ..... 000 0000 0000  @typea_bc
+bge             100111 00101 ..... ..... 000 0000 0000  @typea_bc
+bgt             100111 00100 ..... ..... 000 0000 0000  @typea_bc
+ble             100111 00011 ..... ..... 000 0000 0000  @typea_bc
+blt             100111 00010 ..... ..... 000 0000 0000  @typea_bc
+bne             100111 00001 ..... ..... 000 0000 0000  @typea_bc
+
+beqd            100111 10000 ..... ..... 000 0000 0000  @typea_bc
+bged            100111 10101 ..... ..... 000 0000 0000  @typea_bc
+bgtd            100111 10100 ..... ..... 000 0000 0000  @typea_bc
+bled            100111 10011 ..... ..... 000 0000 0000  @typea_bc
+bltd            100111 10010 ..... ..... 000 0000 0000  @typea_bc
+bned            100111 10001 ..... ..... 000 0000 0000  @typea_bc
+
+beqi            101111 00000 ..... ................     @typeb_bc
+bgei            101111 00101 ..... ................     @typeb_bc
+bgti            101111 00100 ..... ................     @typeb_bc
+blei            101111 00011 ..... ................     @typeb_bc
+blti            101111 00010 ..... ................     @typeb_bc
+bnei            101111 00001 ..... ................     @typeb_bc
+
+beqid           101111 10000 ..... ................     @typeb_bc
+bgeid           101111 10101 ..... ................     @typeb_bc
+bgtid           101111 10100 ..... ................     @typeb_bc
+bleid           101111 10011 ..... ................     @typeb_bc
+bltid           101111 10010 ..... ................     @typeb_bc
+bneid           101111 10001 ..... ................     @typeb_bc
+
 br              100110 ..... 00000 ..... 000 0000 0000  @typea_br
 bra             100110 ..... 01000 ..... 000 0000 0000  @typea_br
 brd             100110 ..... 10000 ..... 000 0000 0000  @typea_br
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 5c6e6e599e..b8dcef8f1c 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1095,6 +1095,58 @@ DO_BR(brad, braid, true, true, false)
 DO_BR(brld, brlid, true, false, true)
 DO_BR(brald, bralid, true, true, true)
 
+static bool do_bcc(DisasContext *dc, int dest_rb, int dest_imm,
+                   TCGCond cond, int ra, bool delay)
+{
+    TCGv_i32 zero, next;
+
+    if (delay) {
+        setup_dslot(dc, dest_rb < 0);
+    }
+
+    dc->jmp_cond = cond;
+
+    /* Cache the condition register in cpu_bvalue across any delay slot.  */
+    tcg_gen_mov_i32(cpu_bvalue, reg_for_read(dc, ra));
+
+    /* Store the branch taken destination into btarget.  */
+    if (dest_rb > 0) {
+        dc->jmp_dest = -1;
+        tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], dc->base.pc_next);
+    } else {
+        dc->jmp_dest = dc->base.pc_next + dest_imm;
+        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
+    }
+
+    /* Compute the final destination into btarget.  */
+    zero = tcg_const_i32(0);
+    next = tcg_const_i32(dc->base.pc_next + (delay + 1) * 4);
+    tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
+                        reg_for_read(dc, ra), zero,
+                        cpu_btarget, next);
+    tcg_temp_free_i32(zero);
+    tcg_temp_free_i32(next);
+
+    return true;
+}
+
+#define DO_BCC(NAME, COND)                                              \
+    static bool trans_##NAME(DisasContext *dc, arg_typea_bc *arg)       \
+    { return do_bcc(dc, arg->rb, 0, COND, arg->ra, false); }            \
+    static bool trans_##NAME##d(DisasContext *dc, arg_typea_bc *arg)    \
+    { return do_bcc(dc, arg->rb, 0, COND, arg->ra, true); }             \
+    static bool trans_##NAME##i(DisasContext *dc, arg_typeb_bc *arg)    \
+    { return do_bcc(dc, -1, arg->imm, COND, arg->ra, false); }          \
+    static bool trans_##NAME##id(DisasContext *dc, arg_typeb_bc *arg)   \
+    { return do_bcc(dc, -1, arg->imm, COND, arg->ra, true); }
+
+DO_BCC(beq, TCG_COND_EQ)
+DO_BCC(bge, TCG_COND_GE)
+DO_BCC(bgt, TCG_COND_GT)
+DO_BCC(ble, TCG_COND_LE)
+DO_BCC(blt, TCG_COND_LT)
+DO_BCC(bne, TCG_COND_NE)
+
 static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
 {
     if (trap_userspace(dc, true)) {
@@ -1419,52 +1471,6 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-static void dec_bcc(DisasContext *dc)
-{
-    static const TCGCond mb_to_tcg_cc[] = {
-        [CC_EQ] = TCG_COND_EQ,
-        [CC_NE] = TCG_COND_NE,
-        [CC_LT] = TCG_COND_LT,
-        [CC_LE] = TCG_COND_LE,
-        [CC_GE] = TCG_COND_GE,
-        [CC_GT] = TCG_COND_GT,
-    };
-    unsigned int cc;
-    unsigned int dslot;
-    TCGv_i32 zero, next;
-
-    cc = EXTRACT_FIELD(dc->ir, 21, 23);
-    dslot = dc->ir & (1 << 25);
-
-    if (dslot) {
-        setup_dslot(dc, dc->type_b);
-    }
-
-    dc->jmp_cond = mb_to_tcg_cc[cc];
-
-    /* Cache the condition register in cpu_bvalue across any delay slot.  */
-    tcg_gen_mov_i32(cpu_bvalue, cpu_R[dc->ra]);
-
-    /* Store the branch taken destination into btarget.  */
-    if (dc->type_b) {
-        dc->jmp_dest = dc->base.pc_next + dec_alu_typeb_imm(dc);
-        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
-    } else {
-        dc->jmp_dest = -1;
-        tcg_gen_addi_i32(cpu_btarget, reg_for_read(dc, dc->rb),
-                         dc->base.pc_next);
-    }
-
-    /* Compute the final destination into btarget.  */
-    zero = tcg_const_i32(0);
-    next = tcg_const_i32(dc->base.pc_next + (dslot + 1) * 4);
-    tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
-                        reg_for_read(dc, dc->ra), zero,
-                        cpu_btarget, next);
-    tcg_temp_free_i32(zero);
-    tcg_temp_free_i32(next);
-}
-
 static inline void do_rti(DisasContext *dc)
 {
     TCGv_i32 t0, t1;
@@ -1595,7 +1601,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_BCC, dec_bcc},
     {DEC_RTS, dec_rts},
     {DEC_MSR, dec_msr},
     {DEC_STREAM, dec_stream},
-- 
2.25.1



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

* [PATCH v2 68/76] target/microblaze: Convert dec_rts to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (66 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 67/76] target/microblaze: Convert dec_bcc " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte Richard Henderson
                   ` (8 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  5 ++++
 target/microblaze/translate.c  | 51 +++++++++++++++-------------------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index e6a61f147a..8906058a29 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -202,6 +202,11 @@ rsubic          001011 ..... ..... ................     @typeb
 rsubik          001101 ..... ..... ................     @typeb
 rsubikc         001111 ..... ..... ................     @typeb
 
+rtbd            101101 10010 ..... ................     @typeb_bc
+rtid            101101 10001 ..... ................     @typeb_bc
+rted            101101 10100 ..... ................     @typeb_bc
+rtsd            101101 10000 ..... ................     @typeb_bc
+
 sb              110100 ..... ..... ..... 0000 000 0000  @typea
 sbr             110100 ..... ..... ..... 0100 000 0000  @typea
 sbea            110100 ..... ..... ..... 0001 000 0000  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index b8dcef8f1c..6c1855b29a 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1252,6 +1252,29 @@ static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
     return true;
 }
 
+static bool do_rts(DisasContext *dc, arg_typeb_bc *arg, int to_set)
+{
+    if (trap_userspace(dc, to_set)) {
+        return true;
+    }
+    dc->tb_flags_to_set |= to_set;
+    setup_dslot(dc, true);
+
+    dc->jmp_cond = TCG_COND_ALWAYS;
+    dc->jmp_dest = -1;
+    tcg_gen_addi_i32(cpu_btarget, reg_for_read(dc, arg->ra), arg->imm);
+    return true;
+}
+
+#define DO_RTS(NAME, IFLAG) \
+    static bool trans_##NAME(DisasContext *dc, arg_typeb_bc *arg) \
+    { return do_rts(dc, arg, IFLAG); }
+
+DO_RTS(rtbd, DRTB_FLAG)
+DO_RTS(rtid, DRTI_FLAG)
+DO_RTS(rted, DRTE_FLAG)
+DO_RTS(rtsd, 0)
+
 static bool trans_zero(DisasContext *dc, arg_zero *arg)
 {
     /* If opcode_0_illegal, trap.  */
@@ -1527,33 +1550,6 @@ static inline void do_rte(DisasContext *dc)
     dc->tb_flags &= ~DRTE_FLAG;
 }
 
-static void dec_rts(DisasContext *dc)
-{
-    unsigned int b_bit, i_bit, e_bit;
-
-    i_bit = dc->ir & (1 << 21);
-    b_bit = dc->ir & (1 << 22);
-    e_bit = dc->ir & (1 << 23);
-
-    if (trap_userspace(dc, i_bit || b_bit || e_bit)) {
-        return;
-    }
-
-    setup_dslot(dc, true);
-
-    if (i_bit) {
-        dc->tb_flags |= DRTI_FLAG;
-    } else if (b_bit) {
-        dc->tb_flags |= DRTB_FLAG;
-    } else if (e_bit) {
-        dc->tb_flags |= DRTE_FLAG;
-    }
-
-    dc->jmp_cond = TCG_COND_ALWAYS;
-    dc->jmp_dest = -1;
-    tcg_gen_add_i32(cpu_btarget, cpu_R[dc->ra], *dec_alu_op_b(dc));
-}
-
 static void dec_null(DisasContext *dc)
 {
     if (trap_illegal(dc, true)) {
@@ -1601,7 +1597,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_RTS, dec_rts},
     {DEC_MSR, dec_msr},
     {DEC_STREAM, dec_stream},
     {{0, 0}, dec_null}
-- 
2.25.1



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

* [PATCH v2 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (67 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 68/76] target/microblaze: Convert dec_rts " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 70/76] target/microblaze: Convert msrclr, msrset to decodetree Richard Henderson
                   ` (7 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Since cpu_msr is no longer a 64-bit quantity, we can simplify
the arithmetic in these functions.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 6c1855b29a..0872795038 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1494,59 +1494,44 @@ static void dec_msr(DisasContext *dc)
     }
 }
 
-static inline void do_rti(DisasContext *dc)
+static void do_rti(DisasContext *dc)
 {
-    TCGv_i32 t0, t1;
-    t0 = tcg_temp_new_i32();
-    t1 = tcg_temp_new_i32();
-    tcg_gen_mov_i32(t1, cpu_msr);
-    tcg_gen_shri_i32(t0, t1, 1);
-    tcg_gen_ori_i32(t1, t1, MSR_IE);
-    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
+    TCGv_i32 tmp = tcg_temp_new_i32();
 
-    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
-    tcg_gen_or_i32(t1, t1, t0);
-    msr_write(dc, t1);
-    tcg_temp_free_i32(t1);
-    tcg_temp_free_i32(t0);
+    tcg_gen_shri_i32(tmp, cpu_msr, 1);
+    tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_IE);
+    tcg_gen_andi_i32(tmp, tmp, MSR_VM | MSR_UM);
+    tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM));
+    tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
+
+    tcg_temp_free_i32(tmp);
     dc->tb_flags &= ~DRTI_FLAG;
 }
 
-static inline void do_rtb(DisasContext *dc)
+static void do_rtb(DisasContext *dc)
 {
-    TCGv_i32 t0, t1;
-    t0 = tcg_temp_new_i32();
-    t1 = tcg_temp_new_i32();
-    tcg_gen_mov_i32(t1, cpu_msr);
-    tcg_gen_andi_i32(t1, t1, ~MSR_BIP);
-    tcg_gen_shri_i32(t0, t1, 1);
-    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
+    TCGv_i32 tmp = tcg_temp_new_i32();
 
-    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
-    tcg_gen_or_i32(t1, t1, t0);
-    msr_write(dc, t1);
-    tcg_temp_free_i32(t1);
-    tcg_temp_free_i32(t0);
+    tcg_gen_shri_i32(tmp, cpu_msr, 1);
+    tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_BIP));
+    tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
+    tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
+
+    tcg_temp_free_i32(tmp);
     dc->tb_flags &= ~DRTB_FLAG;
 }
 
-static inline void do_rte(DisasContext *dc)
+static void do_rte(DisasContext *dc)
 {
-    TCGv_i32 t0, t1;
-    t0 = tcg_temp_new_i32();
-    t1 = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_temp_new_i32();
 
-    tcg_gen_mov_i32(t1, cpu_msr);
-    tcg_gen_ori_i32(t1, t1, MSR_EE);
-    tcg_gen_andi_i32(t1, t1, ~MSR_EIP);
-    tcg_gen_shri_i32(t0, t1, 1);
-    tcg_gen_andi_i32(t0, t0, (MSR_VM | MSR_UM));
+    tcg_gen_shri_i32(tmp, cpu_msr, 1);
+    tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_EE);
+    tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
+    tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_EIP));
+    tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
 
-    tcg_gen_andi_i32(t1, t1, ~(MSR_VM | MSR_UM));
-    tcg_gen_or_i32(t1, t1, t0);
-    msr_write(dc, t1);
-    tcg_temp_free_i32(t1);
-    tcg_temp_free_i32(t0);
+    tcg_temp_free_i32(tmp);
     dc->tb_flags &= ~DRTE_FLAG;
 }
 
-- 
2.25.1



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

* [PATCH v2 70/76] target/microblaze: Convert msrclr, msrset to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (68 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 71/76] target/microblaze: Convert dec_msr " Richard Henderson
                   ` (6 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Split this out of dec_msr.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  6 +++
 target/microblaze/translate.c  | 85 +++++++++++++++++++---------------
 2 files changed, 54 insertions(+), 37 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 8906058a29..ed3312982f 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -24,6 +24,7 @@
 &typeb          rd ra imm
 &typeb_br       rd imm
 &typeb_bc       ra imm
+&type_msr       rd imm
 
 # Include any IMM prefix in the value reported.
 %extimm         0:s16 !function=typeb_imm
@@ -55,6 +56,8 @@
 %ieimm          6:5 0:5
 @typeb_ie       ...... rd:5 ra:5 ..... ..... . .....    &typeb imm=%ieimm
 
+@type_msr       ...... rd:5 ...... imm:15               &type_msr
+
 ###
 
 {
@@ -179,6 +182,9 @@ lwi             111010 ..... ..... ................     @typeb
 
 mbar            101110 imm:5 00010 0000 0000 0000 0100
 
+msrclr          100101 ..... 100010 ...............     @type_msr
+msrset          100101 ..... 100000 ...............     @type_msr
+
 mul             010000 ..... ..... ..... 000 0000 0000  @typea
 mulh            010000 ..... ..... ..... 000 0000 0001  @typea
 mulhu           010000 ..... ..... ..... 000 0000 0011  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 0872795038..9479dbc103 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1311,16 +1311,61 @@ static void msr_write(DisasContext *dc, TCGv_i32 v)
     tcg_gen_andi_i32(cpu_msr, v, ~(MSR_C | MSR_CC | MSR_PVR));
 }
 
+static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
+{
+    uint32_t imm = arg->imm;
+
+    if (trap_userspace(dc, imm != MSR_C)) {
+        return true;
+    }
+
+    if (arg->rd) {
+        msr_read(dc, cpu_R[arg->rd]);
+    }
+
+    /*
+     * Handle the carry bit separately.
+     * This is the only bit that userspace can modify.
+     */
+    if (imm & MSR_C) {
+        tcg_gen_movi_i32(cpu_msr_c, set);
+    }
+
+    /*
+     * MSR_C and MSR_CC set above.
+     * MSR_PVR is not writable, and is always clear.
+     */
+    imm &= ~(MSR_C | MSR_CC | MSR_PVR);
+
+    if (imm != 0) {
+        if (set) {
+            tcg_gen_ori_i32(cpu_msr, cpu_msr, imm);
+        } else {
+            tcg_gen_andi_i32(cpu_msr, cpu_msr, ~imm);
+        }
+        dc->cpustate_changed = 1;
+    }
+    return true;
+}
+
+static bool trans_msrclr(DisasContext *dc, arg_type_msr *arg)
+{
+    return do_msrclrset(dc, arg, false);
+}
+
+static bool trans_msrset(DisasContext *dc, arg_type_msr *arg)
+{
+    return do_msrclrset(dc, arg, true);
+}
+
 static void dec_msr(DisasContext *dc)
 {
     CPUState *cs = CPU(dc->cpu);
-    TCGv_i32 t0, t1;
     unsigned int sr, rn;
-    bool to, clrset, extended = false;
+    bool to, extended = false;
 
     sr = extract32(dc->imm, 0, 14);
     to = extract32(dc->imm, 14, 1);
-    clrset = extract32(dc->imm, 15, 1) == 0;
     dc->type_b = 1;
     if (to) {
         dc->cpustate_changed = 1;
@@ -1334,40 +1379,6 @@ static void dec_msr(DisasContext *dc)
         extended = extract32(dc->imm, e_bit[to], 1);
     }
 
-    /* msrclr and msrset.  */
-    if (clrset) {
-        bool clr = extract32(dc->ir, 16, 1);
-
-        if (!dc->cpu->cfg.use_msr_instr) {
-            /* nop??? */
-            return;
-        }
-
-        if (trap_userspace(dc, dc->imm != 4 && dc->imm != 0)) {
-            return;
-        }
-
-        if (dc->rd)
-            msr_read(dc, cpu_R[dc->rd]);
-
-        t0 = tcg_temp_new_i32();
-        t1 = tcg_temp_new_i32();
-        msr_read(dc, t0);
-        tcg_gen_mov_i32(t1, *(dec_alu_op_b(dc)));
-
-        if (clr) {
-            tcg_gen_not_i32(t1, t1);
-            tcg_gen_and_i32(t0, t0, t1);
-        } else
-            tcg_gen_or_i32(t0, t0, t1);
-        msr_write(dc, t0);
-        tcg_temp_free_i32(t0);
-        tcg_temp_free_i32(t1);
-        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
-        dc->base.is_jmp = DISAS_UPDATE;
-        return;
-    }
-
     if (trap_userspace(dc, to)) {
         return;
     }
-- 
2.25.1



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

* [PATCH v2 71/76] target/microblaze: Convert dec_msr to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (69 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 70/76] target/microblaze: Convert msrclr, msrset to decodetree Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 72/76] target/microblaze: Convert dec_stream " Richard Henderson
                   ` (5 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |   3 +
 target/microblaze/translate.c  | 270 +++++++++++++++++----------------
 2 files changed, 139 insertions(+), 134 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index ed3312982f..43c9e16819 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -182,6 +182,9 @@ lwi             111010 ..... ..... ................     @typeb
 
 mbar            101110 imm:5 00010 0000 0000 0000 0100
 
+mfs             100101 rd:5  0 e:1 000 10 rs:14
+mts             100101 0 e:1 000 ra:5  11 rs:14
+
 msrclr          100101 ..... 100010 ...............     @type_msr
 msrset          100101 ..... 100000 ...............     @type_msr
 
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9479dbc103..582f5a1577 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1300,6 +1300,7 @@ static void msr_read(DisasContext *dc, TCGv_i32 d)
     tcg_temp_free_i32(t);
 }
 
+#ifndef CONFIG_USER_ONLY
 static void msr_write(DisasContext *dc, TCGv_i32 v)
 {
     dc->cpustate_changed = 1;
@@ -1310,6 +1311,7 @@ static void msr_write(DisasContext *dc, TCGv_i32 v)
     /* Clear MSR_C and MSR_CC; MSR_PVR is not writable, and is always clear. */
     tcg_gen_andi_i32(cpu_msr, v, ~(MSR_C | MSR_CC | MSR_PVR));
 }
+#endif
 
 static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
 {
@@ -1358,151 +1360,152 @@ static bool trans_msrset(DisasContext *dc, arg_type_msr *arg)
     return do_msrclrset(dc, arg, true);
 }
 
-static void dec_msr(DisasContext *dc)
+static bool trans_mts(DisasContext *dc, arg_mts *arg)
 {
-    CPUState *cs = CPU(dc->cpu);
-    unsigned int sr, rn;
-    bool to, extended = false;
-
-    sr = extract32(dc->imm, 0, 14);
-    to = extract32(dc->imm, 14, 1);
-    dc->type_b = 1;
-    if (to) {
-        dc->cpustate_changed = 1;
+    if (trap_userspace(dc, true)) {
+        return true;
     }
 
-    /* Extended MSRs are only available if addr_size > 32.  */
-    if (dc->cpu->cfg.addr_size > 32) {
-        /* The E-bit is encoded differently for To/From MSR.  */
-        static const unsigned int e_bit[] = { 19, 24 };
-
-        extended = extract32(dc->imm, e_bit[to], 1);
+#ifdef CONFIG_USER_ONLY
+    g_assert_not_reached();
+#else
+    if (arg->e && arg->rs != 0x1003) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "Invalid extended mts reg 0x%x\n", arg->rs);
+        return true;
     }
 
-    if (trap_userspace(dc, to)) {
-        return;
-    }
+    TCGv_i32 src = reg_for_read(dc, arg->ra);
+    switch (arg->rs) {
+    case SR_MSR:
+        msr_write(dc, src);
+        break;
+    case SR_FSR:
+        tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, fsr));
+        break;
+    case 0x800:
+        tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, slr));
+        break;
+    case 0x802:
+        tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, shr));
+        break;
 
-#if !defined(CONFIG_USER_ONLY)
-    /* Catch read/writes to the mmu block.  */
-    if ((sr & ~0xff) == 0x1000) {
-        TCGv_i32 tmp_ext = tcg_const_i32(extended);
-        TCGv_i32 tmp_sr;
+    case 0x1000: /* PID */
+    case 0x1001: /* ZPR */
+    case 0x1002: /* TLBX */
+    case 0x1003: /* TLBLO */
+    case 0x1004: /* TLBHI */
+    case 0x1005: /* TLBSX */
+        {
+            TCGv_i32 tmp_ext = tcg_const_i32(arg->e);
+            TCGv_i32 tmp_reg = tcg_const_i32(arg->rs & 7);
 
-        sr &= 7;
-        tmp_sr = tcg_const_i32(sr);
-        if (to) {
-            gen_helper_mmu_write(cpu_env, tmp_ext, tmp_sr, cpu_R[dc->ra]);
-        } else {
-            gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tmp_ext, tmp_sr);
+            gen_helper_mmu_write(cpu_env, tmp_ext, tmp_reg, src);
+            tcg_temp_free_i32(tmp_reg);
+            tcg_temp_free_i32(tmp_ext);
         }
-        tcg_temp_free_i32(tmp_sr);
-        tcg_temp_free_i32(tmp_ext);
-        return;
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "Invalid mts reg 0x%x\n", arg->rs);
+        return true;
     }
+    dc->cpustate_changed = 1;
+    return true;
+#endif
+}
+
+static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
+{
+    TCGv_i32 dest = reg_for_write(dc, arg->rd);
+
+    if (arg->e) {
+        switch (arg->rs) {
+        case SR_EAR:
+            {
+                TCGv_i64 t64 = tcg_temp_new_i64();
+                tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
+                tcg_gen_extrh_i64_i32(dest, t64);
+                tcg_temp_free_i64(t64);
+            }
+            return true;
+#ifndef CONFIG_USER_ONLY
+        case 0x1003: /* TLBLO */
+            /* Handled below. */
+            break;
+#endif
+        case 0x2006 ... 0x2009:
+            /* High bits of PVR6-9 not implemented. */
+            tcg_gen_movi_i32(dest, 0);
+            return true;
+        default:
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "Invalid extended mfs reg 0x%x\n", arg->rs);
+            return true;
+        }
+    }
+
+    switch (arg->rs) {
+    case SR_PC:
+        tcg_gen_movi_i32(dest, dc->base.pc_next);
+        break;
+    case SR_MSR:
+        msr_read(dc, dest);
+        break;
+    case SR_EAR:
+        {
+            TCGv_i64 t64 = tcg_temp_new_i64();
+            tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
+            tcg_gen_extrl_i64_i32(dest, t64);
+            tcg_temp_free_i64(t64);
+        }
+        break;
+    case SR_ESR:
+        tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, esr));
+        break;
+    case SR_FSR:
+        tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, fsr));
+        break;
+    case SR_BTR:
+        tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, btr));
+        break;
+    case SR_EDR:
+        tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, edr));
+        break;
+    case 0x800:
+        tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, slr));
+        break;
+    case 0x802:
+        tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, shr));
+        break;
+
+#ifndef CONFIG_USER_ONLY
+    case 0x1000: /* PID */
+    case 0x1001: /* ZPR */
+    case 0x1002: /* TLBX */
+    case 0x1003: /* TLBLO */
+    case 0x1004: /* TLBHI */
+    case 0x1005: /* TLBSX */
+        {
+            TCGv_i32 tmp_ext = tcg_const_i32(arg->e);
+            TCGv_i32 tmp_reg = tcg_const_i32(arg->rs & 7);
+
+            gen_helper_mmu_read(dest, cpu_env, tmp_ext, tmp_reg);
+            tcg_temp_free_i32(tmp_reg);
+            tcg_temp_free_i32(tmp_ext);
+        }
+        break;
 #endif
 
-    if (to) {
-        switch (sr) {
-            case SR_PC:
-                break;
-            case SR_MSR:
-                msr_write(dc, cpu_R[dc->ra]);
-                break;
-            case SR_EAR:
-                {
-                    TCGv_i64 t64 = tcg_temp_new_i64();
-                    tcg_gen_extu_i32_i64(t64, cpu_R[dc->ra]);
-                    tcg_gen_st_i64(t64, cpu_env, offsetof(CPUMBState, ear));
-                    tcg_temp_free_i64(t64);
-                }
-                break;
-            case SR_ESR:
-                tcg_gen_st_i32(cpu_R[dc->ra],
-                               cpu_env, offsetof(CPUMBState, esr));
-                break;
-            case SR_FSR:
-                tcg_gen_st_i32(cpu_R[dc->ra],
-                               cpu_env, offsetof(CPUMBState, fsr));
-                break;
-            case SR_BTR:
-                tcg_gen_st_i32(cpu_R[dc->ra],
-                               cpu_env, offsetof(CPUMBState, btr));
-                break;
-            case SR_EDR:
-                tcg_gen_st_i32(cpu_R[dc->ra],
-                               cpu_env, offsetof(CPUMBState, edr));
-                break;
-            case 0x800:
-                tcg_gen_st_i32(cpu_R[dc->ra],
-                               cpu_env, offsetof(CPUMBState, slr));
-                break;
-            case 0x802:
-                tcg_gen_st_i32(cpu_R[dc->ra],
-                               cpu_env, offsetof(CPUMBState, shr));
-                break;
-            default:
-                cpu_abort(CPU(dc->cpu), "unknown mts reg %x\n", sr);
-                break;
-        }
-    } else {
-        switch (sr) {
-            case SR_PC:
-                tcg_gen_movi_i32(cpu_R[dc->rd], dc->base.pc_next);
-                break;
-            case SR_MSR:
-                msr_read(dc, cpu_R[dc->rd]);
-                break;
-            case SR_EAR:
-                {
-                    TCGv_i64 t64 = tcg_temp_new_i64();
-                    tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
-                    if (extended) {
-                        tcg_gen_extrh_i64_i32(cpu_R[dc->rd], t64);
-                    } else {
-                        tcg_gen_extrl_i64_i32(cpu_R[dc->rd], t64);
-                    }
-                    tcg_temp_free_i64(t64);
-                }
-                break;
-            case SR_ESR:
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                               cpu_env, offsetof(CPUMBState, esr));
-                break;
-            case SR_FSR:
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                               cpu_env, offsetof(CPUMBState, fsr));
-                break;
-            case SR_BTR:
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                               cpu_env, offsetof(CPUMBState, btr));
-                break;
-            case SR_EDR:
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                               cpu_env, offsetof(CPUMBState, edr));
-                break;
-            case 0x800:
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                               cpu_env, offsetof(CPUMBState, slr));
-                break;
-            case 0x802:
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                               cpu_env, offsetof(CPUMBState, shr));
-                break;
-            case 0x2000 ... 0x200c:
-                rn = sr & 0xf;
-                tcg_gen_ld_i32(cpu_R[dc->rd],
-                              cpu_env, offsetof(CPUMBState, pvr.regs[rn]));
-                break;
-            default:
-                cpu_abort(cs, "unknown mfs reg %x\n", sr);
-                break;
-        }
-    }
-
-    if (dc->rd == 0) {
-        tcg_gen_movi_i32(cpu_R[0], 0);
+    case 0x2000 ... 0x200c:
+        tcg_gen_ld_i32(dest, cpu_env,
+                       offsetof(CPUMBState, pvr.regs[arg->rs - 0x2000]));
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "Invalid mfs reg 0x%x\n", arg->rs);
+        break;
     }
+    return true;
 }
 
 static void do_rti(DisasContext *dc)
@@ -1593,7 +1596,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_MSR, dec_msr},
     {DEC_STREAM, dec_stream},
     {{0, 0}, dec_null}
 };
-- 
2.25.1



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

* [PATCH v2 72/76] target/microblaze: Convert dec_stream to decodetree
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (70 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 71/76] target/microblaze: Convert dec_msr " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 73/76] target/microblaze: Remove last of old decoder Richard Henderson
                   ` (4 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/insns.decode |  6 ++++
 target/microblaze/translate.c  | 64 ++++++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/target/microblaze/insns.decode b/target/microblaze/insns.decode
index 43c9e16819..fb0f0e6838 100644
--- a/target/microblaze/insns.decode
+++ b/target/microblaze/insns.decode
@@ -159,6 +159,9 @@ flt             010110 ..... ..... ----- 0101 000 0000  @typea0
 fint            010110 ..... ..... ----- 0110 000 0000  @typea0
 fsqrt           010110 ..... ..... 00000 0111 000 0000  @typea0
 
+get             011011 rd:5  00000 0 ctrl:5 000000 imm:4
+getd            010011 rd:5  00000 rb:5  0 ctrl:5  00000
+
 idiv            010010 ..... ..... ..... 000 0000 0000  @typea
 idivu           010010 ..... ..... ..... 000 0000 0010  @typea
 
@@ -201,6 +204,9 @@ pcmpbf          100000 ..... ..... ..... 100 0000 0000  @typea
 pcmpeq          100010 ..... ..... ..... 100 0000 0000  @typea
 pcmpne          100011 ..... ..... ..... 100 0000 0000  @typea
 
+put             011011 00000 ra:5  1 ctrl:5 000000 imm:4
+putd            010011 00000 ra:5  rb:5  1 ctrl:5  00000
+
 rsub            000001 ..... ..... ..... 000 0000 0000  @typea
 rsubc           000011 ..... ..... ..... 000 0000 0000  @typea
 rsubk           000101 ..... ..... ..... 000 0000 0000  @typea
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 582f5a1577..2c87d671ae 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1560,33 +1560,68 @@ static void dec_null(DisasContext *dc)
 }
 
 /* Insns connected to FSL or AXI stream attached devices.  */
-static void dec_stream(DisasContext *dc)
+static bool do_get(DisasContext *dc, int rd, int rb, int imm, int ctrl)
 {
     TCGv_i32 t_id, t_ctrl;
-    int ctrl;
 
     if (trap_userspace(dc, true)) {
-        return;
+        return true;
     }
 
     t_id = tcg_temp_new_i32();
-    if (dc->type_b) {
-        tcg_gen_movi_i32(t_id, dc->imm & 0xf);
-        ctrl = dc->imm >> 10;
+    if (rb) {
+        tcg_gen_andi_i32(t_id, cpu_R[rb], 0xf);
     } else {
-        tcg_gen_andi_i32(t_id, cpu_R[dc->rb], 0xf);
-        ctrl = dc->imm >> 5;
+        tcg_gen_movi_i32(t_id, imm);
     }
 
     t_ctrl = tcg_const_i32(ctrl);
-
-    if (dc->rd == 0) {
-        gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]);
-    } else {
-        gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl);
-    }
+    gen_helper_get(reg_for_write(dc, rd), t_id, t_ctrl);
     tcg_temp_free_i32(t_id);
     tcg_temp_free_i32(t_ctrl);
+    return true;
+}
+
+static bool trans_get(DisasContext *dc, arg_get *arg)
+{
+    return do_get(dc, arg->rd, 0, arg->imm, arg->ctrl);
+}
+
+static bool trans_getd(DisasContext *dc, arg_getd *arg)
+{
+    return do_get(dc, arg->rd, arg->rb, 0, arg->ctrl);
+}
+
+static bool do_put(DisasContext *dc, int ra, int rb, int imm, int ctrl)
+{
+    TCGv_i32 t_id, t_ctrl;
+
+    if (trap_userspace(dc, true)) {
+        return true;
+    }
+
+    t_id = tcg_temp_new_i32();
+    if (rb) {
+        tcg_gen_andi_i32(t_id, cpu_R[rb], 0xf);
+    } else {
+        tcg_gen_movi_i32(t_id, imm);
+    }
+
+    t_ctrl = tcg_const_i32(ctrl);
+    gen_helper_put(t_id, t_ctrl, reg_for_read(dc, ra));
+    tcg_temp_free_i32(t_id);
+    tcg_temp_free_i32(t_ctrl);
+    return true;
+}
+
+static bool trans_put(DisasContext *dc, arg_put *arg)
+{
+    return do_put(dc, arg->ra, 0, arg->imm, arg->ctrl);
+}
+
+static bool trans_putd(DisasContext *dc, arg_putd *arg)
+{
+    return do_put(dc, arg->ra, arg->rb, 0, arg->ctrl);
 }
 
 static struct decoder_info {
@@ -1596,7 +1631,6 @@ static struct decoder_info {
     };
     void (*dec)(DisasContext *dc);
 } decinfo[] = {
-    {DEC_STREAM, dec_stream},
     {{0, 0}, dec_null}
 };
 
-- 
2.25.1



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

* [PATCH v2 73/76] target/microblaze: Remove last of old decoder
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (71 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 72/76] target/microblaze: Convert dec_stream " Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 74/76] target/microblaze: Remove cpu_R[0] Richard Henderson
                   ` (3 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

All instructions have been convered.  Issue sigill if decodetree
does not match.  Remove argument decode from DisasContext.
Remove microblaze-decode.h.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/microblaze-decode.h | 59 ----------------------
 target/microblaze/translate.c         | 73 +--------------------------
 2 files changed, 1 insertion(+), 131 deletions(-)
 delete mode 100644 target/microblaze/microblaze-decode.h

diff --git a/target/microblaze/microblaze-decode.h b/target/microblaze/microblaze-decode.h
deleted file mode 100644
index 17b2f29fff..0000000000
--- a/target/microblaze/microblaze-decode.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  MicroBlaze insn decoding macros.
- *
- *  Copyright (c) 2009 Edgar E. Iglesias <edgar.iglesias@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TARGET_MICROBLAZE_MICROBLAZE_DECODE_H
-#define TARGET_MICROBLAZE_MICROBLAZE_DECODE_H
-
-/* Convenient binary macros.  */
-#define HEX__(n) 0x##n##LU
-#define B8__(x) ((x&0x0000000FLU)?1:0) \
-                 + ((x&0x000000F0LU)?2:0) \
-                 + ((x&0x00000F00LU)?4:0) \
-                 + ((x&0x0000F000LU)?8:0) \
-                 + ((x&0x000F0000LU)?16:0) \
-                 + ((x&0x00F00000LU)?32:0) \
-                 + ((x&0x0F000000LU)?64:0) \
-                 + ((x&0xF0000000LU)?128:0)
-#define B8(d) ((unsigned char)B8__(HEX__(d)))
-
-/* Decode logic, value and mask.  */
-#define DEC_ADD     {B8(00000000), B8(00110001)}
-#define DEC_SUB     {B8(00000001), B8(00110001)}
-#define DEC_AND     {B8(00100001), B8(00110101)}
-#define DEC_XOR     {B8(00100010), B8(00110111)}
-#define DEC_OR      {B8(00100000), B8(00110111)}
-#define DEC_BIT     {B8(00100100), B8(00111111)}
-#define DEC_MSR     {B8(00100101), B8(00111111)}
-
-#define DEC_BARREL  {B8(00010001), B8(00110111)}
-#define DEC_MUL     {B8(00010000), B8(00110111)}
-#define DEC_DIV     {B8(00010010), B8(00110111)}
-#define DEC_FPU     {B8(00010110), B8(00111111)}
-
-#define DEC_LD      {B8(00110000), B8(00110100)}
-#define DEC_ST      {B8(00110100), B8(00110100)}
-#define DEC_IMM     {B8(00101100), B8(00111111)}
-
-#define DEC_BR      {B8(00100110), B8(00110111)}
-#define DEC_BCC     {B8(00100111), B8(00110111)}
-#define DEC_RTS     {B8(00101101), B8(00111111)}
-
-#define DEC_STREAM  {B8(00010011), B8(00110111)}
-
-#endif
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 2c87d671ae..8f69ca50b2 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -24,7 +24,6 @@
 #include "exec/exec-all.h"
 #include "tcg/tcg-op.h"
 #include "exec/helper-proto.h"
-#include "microblaze-decode.h"
 #include "exec/cpu_ldst.h"
 #include "exec/helper-gen.h"
 #include "exec/translator.h"
@@ -65,13 +64,7 @@ typedef struct DisasContext {
     bool r0_set;
 
     /* Decoder.  */
-    int type_b;
-    uint32_t ir;
     uint32_t ext_imm;
-    uint8_t opcode;
-    uint8_t rd, ra, rb;
-    uint16_t imm;
-
     unsigned int cpustate_changed;
     unsigned int tb_flags;
     unsigned int tb_flags_to_set;
@@ -82,8 +75,6 @@ typedef struct DisasContext {
 
     /* Immediate branch-taken destination, or -1 for indirect. */
     uint32_t jmp_dest;
-
-    int abort_at_next_insn;
 } DisasContext;
 
 static int typeb_imm(DisasContext *dc, int x)
@@ -184,21 +175,6 @@ static bool trap_userspace(DisasContext *dc, bool cond)
     return cond_user;
 }
 
-static int32_t dec_alu_typeb_imm(DisasContext *dc)
-{
-    tcg_debug_assert(dc->type_b);
-    return typeb_imm(dc, (int16_t)dc->imm);
-}
-
-static inline TCGv_i32 *dec_alu_op_b(DisasContext *dc)
-{
-    if (dc->type_b) {
-        tcg_gen_movi_i32(cpu_imm, dec_alu_typeb_imm(dc));
-        return &cpu_imm;
-    }
-    return &cpu_R[dc->rb];
-}
-
 static TCGv_i32 reg_for_read(DisasContext *dc, int reg)
 {
     if (likely(reg != 0)) {
@@ -1549,16 +1525,6 @@ static void do_rte(DisasContext *dc)
     dc->tb_flags &= ~DRTE_FLAG;
 }
 
-static void dec_null(DisasContext *dc)
-{
-    if (trap_illegal(dc, true)) {
-        return;
-    }
-    qemu_log_mask(LOG_GUEST_ERROR, "unknown insn pc=%x opc=%x\n",
-                  (uint32_t)dc->base.pc_next, dc->opcode);
-    dc->abort_at_next_insn = 1;
-}
-
 /* Insns connected to FSL or AXI stream attached devices.  */
 static bool do_get(DisasContext *dc, int rd, int rb, int imm, int ctrl)
 {
@@ -1624,40 +1590,6 @@ static bool trans_putd(DisasContext *dc, arg_putd *arg)
     return do_put(dc, arg->ra, arg->rb, 0, arg->ctrl);
 }
 
-static struct decoder_info {
-    struct {
-        uint32_t bits;
-        uint32_t mask;
-    };
-    void (*dec)(DisasContext *dc);
-} decinfo[] = {
-    {{0, 0}, dec_null}
-};
-
-static void old_decode(DisasContext *dc, uint32_t ir)
-{
-    int i;
-
-    dc->ir = ir;
-
-    /* bit 2 seems to indicate insn type.  */
-    dc->type_b = ir & (1 << 29);
-
-    dc->opcode = EXTRACT_FIELD(ir, 26, 31);
-    dc->rd = EXTRACT_FIELD(ir, 21, 25);
-    dc->ra = EXTRACT_FIELD(ir, 16, 20);
-    dc->rb = EXTRACT_FIELD(ir, 11, 15);
-    dc->imm = EXTRACT_FIELD(ir, 0, 15);
-
-    /* Large switch for all insns.  */
-    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
-        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
-            decinfo[i].dec(dc);
-            break;
-        }
-    }
-}
-
 static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
 {
     DisasContext *dc = container_of(dcb, DisasContext, base);
@@ -1667,7 +1599,6 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->cpu = cpu;
     dc->tb_flags = dc->base.tb->flags;
     dc->cpustate_changed = 0;
-    dc->abort_at_next_insn = 0;
     dc->ext_imm = dc->base.tb->cs_base;
     dc->r0 = NULL;
     dc->r0_set = false;
@@ -1724,7 +1655,7 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
 
     ir = cpu_ldl_code(env, dc->base.pc_next);
     if (!decode(dc, ir)) {
-        old_decode(dc, ir);
+        trap_illegal(dc, true);
     }
 
     if (dc->r0) {
@@ -1764,8 +1695,6 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
 {
     DisasContext *dc = container_of(dcb, DisasContext, base);
 
-    assert(!dc->abort_at_next_insn);
-
     if (dc->base.is_jmp == DISAS_NORETURN) {
         /* We have already exited the TB. */
         return;
-- 
2.25.1



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

* [PATCH v2 74/76] target/microblaze: Remove cpu_R[0]
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (72 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 73/76] target/microblaze: Remove last of old decoder Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 75/76] target/microblaze: Add flags markup to some helpers Richard Henderson
                   ` (2 subsequent siblings)
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Do not initialize cpu_R[0], as this should be totally unused.
The cpu_for_read and cpu_for_write functions use a local temp.

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

diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 8f69ca50b2..8c287457a9 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1842,7 +1842,13 @@ void mb_tcg_init(void)
     static const struct {
         TCGv_i32 *var; int ofs; char name[8];
     } i32s[] = {
-        R(0),  R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
+        /*
+         * Note that r0 is handled specially in reg_for_read
+         * and reg_for_write.  Nothing should touch cpu_R[0].
+         * Leave that element NULL, which will assert quickly
+         * inside the tcg generator functions.
+         */
+               R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
         R(8),  R(9),  R(10), R(11), R(12), R(13), R(14), R(15),
         R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
         R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
-- 
2.25.1



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

* [PATCH v2 75/76] target/microblaze: Add flags markup to some helpers
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (73 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 74/76] target/microblaze: Remove cpu_R[0] Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-28 14:19 ` [PATCH v2 76/76] target/microblaze: Reduce linux-user address space to 32-bit Richard Henderson
  2020-08-31 14:14 ` [PATCH v2 00/76] target/microblaze improvements Edgar E. Iglesias
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

The mmu_read, mmu_write, get, and put helpers do not touch the
general registers, or any of the other variables managed by tcg.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/helper.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/microblaze/helper.h b/target/microblaze/helper.h
index 3980fba797..f740835fcb 100644
--- a/target/microblaze/helper.h
+++ b/target/microblaze/helper.h
@@ -21,11 +21,11 @@ DEF_HELPER_FLAGS_3(fcmp_ge, TCG_CALL_NO_WG, i32, env, i32, i32)
 
 DEF_HELPER_FLAGS_2(pcmpbf, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 #if !defined(CONFIG_USER_ONLY)
-DEF_HELPER_3(mmu_read, i32, env, i32, i32)
-DEF_HELPER_4(mmu_write, void, env, i32, i32, i32)
+DEF_HELPER_FLAGS_3(mmu_read, TCG_CALL_NO_RWG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_4(mmu_write, TCG_CALL_NO_RWG, void, env, i32, i32, i32)
 #endif
 
 DEF_HELPER_FLAGS_2(stackprot, TCG_CALL_NO_WG, void, env, tl)
 
-DEF_HELPER_2(get, i32, i32, i32)
-DEF_HELPER_3(put, void, i32, i32, i32)
+DEF_HELPER_FLAGS_2(get, TCG_CALL_NO_RWG, i32, i32, i32)
+DEF_HELPER_FLAGS_3(put, TCG_CALL_NO_RWG, void, i32, i32, i32)
-- 
2.25.1



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

* [PATCH v2 76/76] target/microblaze: Reduce linux-user address space to 32-bit
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (74 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 75/76] target/microblaze: Add flags markup to some helpers Richard Henderson
@ 2020-08-28 14:19 ` Richard Henderson
  2020-08-31 14:14 ` [PATCH v2 00/76] target/microblaze improvements Edgar E. Iglesias
  76 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-28 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

User-space programs cannot use the 64-bit lwea/swea instructions.
We can improve code generation and runtime by restricting the
user-only address space to 32-bit.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/microblaze/cpu-param.h | 15 +++++++++++++++
 target/microblaze/cpu.h       |  2 +-
 target/microblaze/helper.c    |  4 ++--
 target/microblaze/translate.c | 28 +++++++++++++++++++++++++++-
 4 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/target/microblaze/cpu-param.h b/target/microblaze/cpu-param.h
index 4abbc62d50..4d8297fa94 100644
--- a/target/microblaze/cpu-param.h
+++ b/target/microblaze/cpu-param.h
@@ -8,9 +8,24 @@
 #ifndef MICROBLAZE_CPU_PARAM_H
 #define MICROBLAZE_CPU_PARAM_H 1
 
+/*
+ * While system mode can address up to 64 bits of address space,
+ * this is done via the lea/sea instructions, which are system-only
+ * (as they also bypass the mmu).
+ *
+ * We can improve the user-only experience by only exposing 32 bits
+ * of address space.
+ */
+#ifdef CONFIG_USER_ONLY
+#define TARGET_LONG_BITS 32
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#else
 #define TARGET_LONG_BITS 64
 #define TARGET_PHYS_ADDR_SPACE_BITS 64
 #define TARGET_VIRT_ADDR_SPACE_BITS 64
+#endif
+
 /* FIXME: MB uses variable pages down to 1K but linux only uses 4k.  */
 #define TARGET_PAGE_BITS 12
 #define NB_MMU_MODES 3
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 4298f242a6..d11b6fa995 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -242,7 +242,7 @@ struct CPUMBState {
     uint32_t pc;
     uint32_t msr;    /* All bits of MSR except MSR[C] and MSR[CC] */
     uint32_t msr_c;  /* MSR[C], in low bit; other bits must be 0 */
-    uint64_t ear;
+    target_ulong ear;
     uint32_t esr;
     uint32_t fsr;
     uint32_t btr;
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 1667822fb7..48547385b0 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -303,8 +303,8 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
     iflags = cpu->env.iflags;
 
     qemu_log_mask(CPU_LOG_INT,
-                  "Unaligned access addr=" TARGET_FMT_lx
-                  " pc=%x iflags=%x\n", addr, cpu->env.pc, iflags);
+                  "Unaligned access addr=" TARGET_FMT_lx " pc=%x iflags=%x\n",
+                  (target_ulong)addr, cpu->env.pc, iflags);
 
     esr = ESR_EC_UNALIGNED_DATA;
     if (likely(iflags & ESR_ESS_FLAG)) {
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 8c287457a9..a377818b5e 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -687,6 +687,7 @@ static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
     return ret;
 }
 
+#ifndef CONFIG_USER_ONLY
 static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
 {
     int addr_size = dc->cpu->cfg.addr_size;
@@ -712,6 +713,7 @@ static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
     }
     return ret;
 }
+#endif
 
 static void record_unaligned_ess(DisasContext *dc, int rd,
                                  MemOp size, bool store)
@@ -776,8 +778,12 @@ static bool trans_lbuea(DisasContext *dc, arg_typea *arg)
     if (trap_userspace(dc, true)) {
         return true;
     }
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
     return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
+#endif
 }
 
 static bool trans_lbui(DisasContext *dc, arg_typeb *arg)
@@ -803,8 +809,12 @@ static bool trans_lhuea(DisasContext *dc, arg_typea *arg)
     if (trap_userspace(dc, true)) {
         return true;
     }
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
     return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
+#endif
 }
 
 static bool trans_lhui(DisasContext *dc, arg_typeb *arg)
@@ -830,8 +840,12 @@ static bool trans_lwea(DisasContext *dc, arg_typea *arg)
     if (trap_userspace(dc, true)) {
         return true;
     }
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
     return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
+#endif
 }
 
 static bool trans_lwi(DisasContext *dc, arg_typeb *arg)
@@ -910,8 +924,12 @@ static bool trans_sbea(DisasContext *dc, arg_typea *arg)
     if (trap_userspace(dc, true)) {
         return true;
     }
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
     return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
+#endif
 }
 
 static bool trans_sbi(DisasContext *dc, arg_typeb *arg)
@@ -937,8 +955,12 @@ static bool trans_shea(DisasContext *dc, arg_typea *arg)
     if (trap_userspace(dc, true)) {
         return true;
     }
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
     return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
+#endif
 }
 
 static bool trans_shi(DisasContext *dc, arg_typeb *arg)
@@ -964,8 +986,12 @@ static bool trans_swea(DisasContext *dc, arg_typea *arg)
     if (trap_userspace(dc, true)) {
         return true;
     }
+#ifdef CONFIG_USER_ONLY
+    return true;
+#else
     TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
     return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
+#endif
 }
 
 static bool trans_swi(DisasContext *dc, arg_typeb *arg)
@@ -1818,7 +1844,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     }
 
     qemu_fprintf(f, "\nesr=0x%04x fsr=0x%02x btr=0x%08x edr=0x%x\n"
-                 "ear=0x%016" PRIx64 " slr=0x%x shr=0x%x\n",
+                 "ear=0x" TARGET_FMT_lx " slr=0x%x shr=0x%x\n",
                  env->esr, env->fsr, env->btr, env->edr,
                  env->ear, env->slr, env->shr);
 
-- 
2.25.1



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

* Re: [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb
  2020-08-28 14:18 ` [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
@ 2020-08-31 13:54   ` Edgar E. Iglesias
  2020-08-31 14:55     ` Richard Henderson
  0 siblings, 1 reply; 92+ messages in thread
From: Edgar E. Iglesias @ 2020-08-31 13:54 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Fri, Aug 28, 2020 at 07:18:40AM -0700, Richard Henderson wrote:
> Do not use goto_tb if we're single-stepping.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/microblaze/translate.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 53ca0bfb38..7d5b96c38b 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -140,7 +140,12 @@ static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
>  
>  static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
>  {
> -    if (use_goto_tb(dc, dest)) {
> +    if (dc->singlestep_enabled) {
> +        TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
> +        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);

This needs to be i32 cpu_pc to avoid breaking bisection. Looks like this
part slipped over to the next patch.

With that fixed:
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>



> +        gen_helper_raise_exception(cpu_env, tmp);
> +        tcg_temp_free_i32(tmp);
> +    } else if (use_goto_tb(dc, dest)) {
>          tcg_gen_goto_tb(n);
>          tcg_gen_movi_i32(cpu_pc, dest);
>          tcg_gen_exit_tb(dc->tb, n);
> -- 
> 2.25.1
> 


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

* Re: [PATCH v2 00/76] target/microblaze improvements
  2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
                   ` (75 preceding siblings ...)
  2020-08-28 14:19 ` [PATCH v2 76/76] target/microblaze: Reduce linux-user address space to 32-bit Richard Henderson
@ 2020-08-31 14:14 ` Edgar E. Iglesias
  76 siblings, 0 replies; 92+ messages in thread
From: Edgar E. Iglesias @ 2020-08-31 14:14 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Fri, Aug 28, 2020 at 07:18:13AM -0700, Richard Henderson wrote:
> Thanks for all the testing and review, Edgar.
> 
> Changes in v2:
>   * Restored opcode_0_illegal handling.
>   * Dropped problematic imm/delay slot tb extension.
>   * Dropped tcg_gen_lookup_and_goto_ptr for now.
>   * Added fix for mb_cpu_transaction_failed.
>   * Removed microblaze-decode.h with old decoder.
>   * Removed abort_at_next_insn with old decoder.
>   * Fixed mbar.
>   * Fixed put.
> 
> 
> r~

I had one more comment on patch #27 but the rest of the series looks good to
me and it also passes my tests.

So once you fix #27 feel free to add my RB & TB tags on the entire series.
It's probably easiest if you send a pull-req via one of your trees.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Thanks again for working on this!
Cheers,
Edgar


> 
> 
> Richard Henderson (76):
>   tests/tcg: Add microblaze to arches filter
>   tests/tcg: Do not require FE_TOWARDZERO
>   tests/tcg: Do not require FE_* exception bits
>   target/microblaze: Tidy gdbstub
>   target/microblaze: Split out PC from env->sregs
>   target/microblaze: Split out MSR from env->sregs
>   target/microblaze: Split out EAR from env->sregs
>   target/microblaze: Split out ESR from env->sregs
>   target/microblaze: Split out FSR from env->sregs
>   target/microblaze: Split out BTR from env->sregs
>   target/microblaze: Split out EDR from env->sregs
>   target/microblaze: Split the cpu_SR array
>   target/microblaze: Fix width of PC and BTARGET
>   target/microblaze: Fix width of MSR
>   target/microblaze: Fix width of ESR
>   target/microblaze: Fix width of FSR
>   target/microblaze: Fix width of BTR
>   target/microblaze: Fix width of EDR
>   target/microblaze: Remove cpu_ear
>   target/microblaze: Tidy raising of exceptions
>   target/microblaze: Mark raise_exception as noreturn
>   target/microblaze: Remove helper_debug and env->debug
>   target/microblaze: Rename env_* tcg variables to cpu_*
>   target/microblaze: Tidy mb_tcg_init
>   target/microblaze: Split out MSR[C] to its own variable
>   target/microblaze: Use DISAS_NORETURN
>   target/microblaze: Check singlestep_enabled in gen_goto_tb
>   target/microblaze: Convert to DisasContextBase
>   target/microblaze: Convert to translator_loop
>   target/microblaze: Remove SIM_COMPAT
>   target/microblaze: Remove DISAS_GNU
>   target/microblaze: Remove empty D macros
>   target/microblaze: Remove LOG_DIS
>   target/microblaze: Ensure imm constant is always available
>   target/microblaze: Add decodetree infrastructure
>   target/microblaze: Convert dec_add to decodetree
>   target/microblaze: Convert dec_sub to decodetree
>   target/microblaze: Implement cmp and cmpu inline
>   target/microblaze: Convert dec_pattern to decodetree
>   target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree
>   target/microblaze: Convert dec_mul to decodetree
>   target/microblaze: Convert dec_div to decodetree
>   target/microblaze: Unwind properly when raising divide-by-zero
>   target/microblaze: Convert dec_bit to decodetree
>   target/microblaze: Convert dec_barrel to decodetree
>   target/microblaze: Convert dec_imm to decodetree
>   target/microblaze: Convert dec_fpu to decodetree
>   target/microblaze: Fix cpu unwind for fpu exceptions
>   target/microblaze: Mark fpu helpers TCG_CALL_NO_WG
>   target/microblaze: Replace MSR_EE_FLAG with MSR_EE
>   target/microblaze: Cache mem_index in DisasContext
>   target/microblaze: Fix cpu unwind for stackprot
>   target/microblaze: Convert dec_load and dec_store to decodetree
>   target/microblaze: Assert no overlap in flags making up tb_flags
>   target/microblaze: Move bimm to BIMM_FLAG
>   target/microblaze: Fix no-op mb_cpu_transaction_failed
>   target/microblaze: Store "current" iflags in insn_start
>   tcg: Add tcg_get_insn_start_param
>   target/microblaze: Use cc->do_unaligned_access
>   target/microblaze: Replace clear_imm with tb_flags_to_set
>   target/microblaze: Replace delayed_branch with tb_flags_to_set
>   target/microblaze: Tidy mb_cpu_dump_state
>   target/microblaze: Convert brk and brki to decodetree
>   target/microblaze: Convert mbar to decodetree
>   target/microblaze: Reorganize branching
>   target/microblaze: Convert dec_br to decodetree
>   target/microblaze: Convert dec_bcc to decodetree
>   target/microblaze: Convert dec_rts to decodetree
>   target/microblaze: Tidy do_rti, do_rtb, do_rte
>   target/microblaze: Convert msrclr, msrset to decodetree
>   target/microblaze: Convert dec_msr to decodetree
>   target/microblaze: Convert dec_stream to decodetree
>   target/microblaze: Remove last of old decoder
>   target/microblaze: Remove cpu_R[0]
>   target/microblaze: Add flags markup to some helpers
>   target/microblaze: Reduce linux-user address space to 32-bit
> 
>  include/tcg/tcg.h                     |   15 +
>  target/microblaze/cpu-param.h         |   15 +
>  target/microblaze/cpu.h               |   67 +-
>  target/microblaze/helper.h            |   49 +-
>  target/microblaze/microblaze-decode.h |   59 -
>  tests/tcg/multiarch/float_helpers.h   |   17 +
>  target/microblaze/insns.decode        |  256 ++
>  linux-user/elfload.c                  |    9 +-
>  linux-user/microblaze/cpu_loop.c      |   26 +-
>  linux-user/microblaze/signal.c        |    8 +-
>  target/microblaze/cpu.c               |    9 +-
>  target/microblaze/gdbstub.c           |  193 +-
>  target/microblaze/helper.c            |  164 +-
>  target/microblaze/mmu.c               |    4 +-
>  target/microblaze/op_helper.c         |  194 +-
>  target/microblaze/translate.c         | 3223 +++++++++++++------------
>  tests/tcg/multiarch/float_convs.c     |    2 +
>  tests/tcg/multiarch/float_madds.c     |    2 +
>  target/microblaze/meson.build         |    3 +
>  tests/tcg/configure.sh                |    2 +-
>  20 files changed, 2292 insertions(+), 2025 deletions(-)
>  delete mode 100644 target/microblaze/microblaze-decode.h
>  create mode 100644 target/microblaze/insns.decode
> 
> -- 
> 2.25.1
> 


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

* Re: [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb
  2020-08-31 13:54   ` Edgar E. Iglesias
@ 2020-08-31 14:55     ` Richard Henderson
  0 siblings, 0 replies; 92+ messages in thread
From: Richard Henderson @ 2020-08-31 14:55 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: qemu-devel

On 8/31/20 6:54 AM, Edgar E. Iglesias wrote:
>> +        TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
>> +        tcg_gen_movi_i64(cpu_SR[SR_PC], dest);
> 
> This needs to be i32 cpu_pc to avoid breaking bisection. Looks like this
> part slipped over to the next patch.
> 
> With that fixed:
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Whoops, yes.  Thanks.


r~


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

* Re: [PATCH v2 03/76] tests/tcg: Do not require FE_* exception bits
  2020-08-28 14:18 ` [PATCH v2 03/76] tests/tcg: Do not require FE_* exception bits Richard Henderson
@ 2020-08-31 17:30   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 17:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 1285 bytes --]

Le ven. 28 août 2020 16:22, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> Define anything that is missing as 0, so that flags & FE_FOO
> is false for any missing FOO.
>
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  tests/tcg/multiarch/float_helpers.h | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>
> diff --git a/tests/tcg/multiarch/float_helpers.h
> b/tests/tcg/multiarch/float_helpers.h
> index 6337bc66c1..309f3f4bf1 100644
> --- a/tests/tcg/multiarch/float_helpers.h
> +++ b/tests/tcg/multiarch/float_helpers.h
> @@ -8,6 +8,23 @@
>
>  #include <inttypes.h>
>
> +/* Some hosts do not have support for all of these; not required by ISO
> C. */
> +#ifndef FE_OVERFLOW
> +#define FE_OVERFLOW 0
> +#endif
> +#ifndef FE_UNDERFLOW
> +#define FE_UNDERFLOW 0
> +#endif
> +#ifndef FE_DIVBYZERO
> +#define FE_DIVBYZERO 0
> +#endif
> +#ifndef FE_INEXACT
> +#define FE_INEXACT 0
> +#endif
> +#ifndef FE_INVALID
> +#define FE_INVALID 0
> +#endif
> +
>  /* Number of constants in each table */
>  int get_num_f16(void);
>  int get_num_f32(void);
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 2338 bytes --]

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

* Re: [PATCH v2 02/76] tests/tcg: Do not require FE_TOWARDZERO
  2020-08-28 14:18 ` [PATCH v2 02/76] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
@ 2020-08-31 17:31   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 17:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 1395 bytes --]

Le ven. 28 août 2020 16:22, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> This is optional in ISO C, and not all cpus provide it.
>
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  tests/tcg/multiarch/float_convs.c | 2 ++
>  tests/tcg/multiarch/float_madds.c | 2 ++
>  2 files changed, 4 insertions(+)
>
> diff --git a/tests/tcg/multiarch/float_convs.c
> b/tests/tcg/multiarch/float_convs.c
> index 47e24b8b16..e9be75c2d5 100644
> --- a/tests/tcg/multiarch/float_convs.c
> +++ b/tests/tcg/multiarch/float_convs.c
> @@ -30,7 +30,9 @@ float_mapping round_flags[] = {
>  #ifdef FE_DOWNWARD
>      { FE_DOWNWARD, "downwards" },
>  #endif
> +#ifdef FE_TOWARDZERO
>      { FE_TOWARDZERO, "to zero" }
> +#endif
>  };
>
>  static void print_input(float input)
> diff --git a/tests/tcg/multiarch/float_madds.c
> b/tests/tcg/multiarch/float_madds.c
> index eceb4ae38b..e422608ccd 100644
> --- a/tests/tcg/multiarch/float_madds.c
> +++ b/tests/tcg/multiarch/float_madds.c
> @@ -29,7 +29,9 @@ float_mapping round_flags[] = {
>  #ifdef FE_DOWNWARD
>      { FE_DOWNWARD, "downwards" },
>  #endif
> +#ifdef FE_TOWARDZERO
>      { FE_TOWARDZERO, "to zero" }
> +#endif
>  };
>
>
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 2495 bytes --]

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

* Re: [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter
  2020-08-28 14:18 ` [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
@ 2020-08-31 17:32   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 17:32 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

Le ven. 28 août 2020 16:20, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> Not attempting to use a single cross-compiler for both
> big-endian and little-endian at this time.
>
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  tests/tcg/configure.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
> index 7d714f902a..598a50cd4f 100755
> --- a/tests/tcg/configure.sh
> +++ b/tests/tcg/configure.sh
> @@ -94,7 +94,7 @@ for target in $target_list; do
>      xtensa|xtensaeb)
>        arches=xtensa
>        ;;
> -    alpha|cris|hppa|i386|lm32|m68k|openrisc|riscv64|s390x|sh4|sparc64)
> +
> alpha|cris|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64)
>        arches=$target
>        ;;
>      *)
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 2052 bytes --]

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

* Re: [PATCH v2 07/76] target/microblaze: Split out EAR from env->sregs
  2020-08-28 14:18 ` [PATCH v2 07/76] target/microblaze: Split out EAR " Richard Henderson
@ 2020-08-31 20:50   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 20:50 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 6913 bytes --]

Le ven. 28 août 2020 16:23, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> Continue eliminating the sregs array in favor of individual members.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  target/microblaze/cpu.h       | 1 +
>  target/microblaze/gdbstub.c   | 4 ++--
>  target/microblaze/helper.c    | 6 +++---
>  target/microblaze/op_helper.c | 8 ++++----
>  target/microblaze/translate.c | 6 ++++--
>  5 files changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index 36de61d9f9..c9035b410e 100644
> --- a/target/microblaze/cpu.h
> +++ b/target/microblaze/cpu.h
> @@ -238,6 +238,7 @@ struct CPUMBState {
>      uint32_t regs[32];
>      uint64_t pc;
>      uint64_t msr;
> +    uint64_t ear;
>      uint64_t sregs[14];
>      float_status fp_status;
>      /* Stack protectors. Yes, it's a hw feature.  */
> diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
> index e4c4936a7a..e33a613efe 100644
> --- a/target/microblaze/gdbstub.c
> +++ b/target/microblaze/gdbstub.c
> @@ -65,7 +65,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray
> *mem_buf, int n)
>          val = env->msr;
>          break;
>      case GDB_EAR:
> -        val = env->sregs[SR_EAR];
> +        val = env->ear;
>          break;
>      case GDB_ESR:
>          val = env->sregs[SR_ESR];
> @@ -121,7 +121,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t
> *mem_buf, int n)
>          env->msr = tmp;
>          break;
>      case GDB_EAR:
> -        env->sregs[SR_EAR] = tmp;
> +        env->ear = tmp;
>          break;
>      case GDB_ESR:
>          env->sregs[SR_ESR] = tmp;
> diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
> index a18314540f..afe9634781 100644
> --- a/target/microblaze/helper.c
> +++ b/target/microblaze/helper.c
> @@ -85,7 +85,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int
> size,
>      qemu_log_mask(CPU_LOG_MMU, "mmu=%d miss v=%" VADDR_PRIx "\n",
>                    mmu_idx, address);
>
> -    env->sregs[SR_EAR] = address;
> +    env->ear = address;
>      switch (lu.err) {
>      case ERR_PROT:
>          env->sregs[SR_ESR] = access_type == MMU_INST_FETCH ? 17 : 16;
> @@ -145,7 +145,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              qemu_log_mask(CPU_LOG_INT,
>                            "hw exception at pc=%" PRIx64 " ear=%" PRIx64 "
> "
>                            "esr=%" PRIx64 " iflags=%x\n",
> -                          env->pc, env->sregs[SR_EAR],
> +                          env->pc, env->ear,
>                            env->sregs[SR_ESR], env->iflags);
>              log_cpu_state_mask(CPU_LOG_INT, cs, 0);
>              env->iflags &= ~(IMM_FLAG | D_FLAG);
> @@ -188,7 +188,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              qemu_log_mask(CPU_LOG_INT,
>                            "exception at pc=%" PRIx64 " ear=%" PRIx64 " "
>                            "iflags=%x\n",
> -                          env->pc, env->sregs[SR_EAR], env->iflags);
> +                          env->pc, env->ear, env->iflags);
>              log_cpu_state_mask(CPU_LOG_INT, cs, 0);
>              env->iflags &= ~(IMM_FLAG | D_FLAG);
>              env->pc = cpu->cfg.base_vectors + 0x20;
> diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
> index 3668382d36..5bacd29663 100644
> --- a/target/microblaze/op_helper.c
> +++ b/target/microblaze/op_helper.c
> @@ -78,7 +78,7 @@ void helper_debug(CPUMBState *env)
>      qemu_log("PC=%" PRIx64 "\n", env->pc);
>      qemu_log("rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
>               "debug[%x] imm=%x iflags=%x\n",
> -             env->msr, env->sregs[SR_ESR], env->sregs[SR_EAR],
> +             env->msr, env->sregs[SR_ESR], env->ear,
>               env->debug, env->imm, env->iflags);
>      qemu_log("btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) eip=%d
> ie=%d\n",
>               env->btaken, env->btarget,
> @@ -431,7 +431,7 @@ void helper_memalign(CPUMBState *env, target_ulong
> addr,
>                            "unaligned access addr=" TARGET_FMT_lx
>                            " mask=%x, wr=%d dr=r%d\n",
>                            addr, mask, wr, dr);
> -            env->sregs[SR_EAR] = addr;
> +            env->ear = addr;
>              env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \
>                                   | (dr & 31) << 5;
>              if (mask == 3) {
> @@ -450,7 +450,7 @@ void helper_stackprot(CPUMBState *env, target_ulong
> addr)
>          qemu_log_mask(CPU_LOG_INT, "Stack protector violation at "
>                        TARGET_FMT_lx " %x %x\n",
>                        addr, env->slr, env->shr);
> -        env->sregs[SR_EAR] = addr;
> +        env->ear = addr;
>          env->sregs[SR_ESR] = ESR_EC_STACKPROT;
>          helper_raise_exception(env, EXCP_HW_EXCP);
>      }
> @@ -488,7 +488,7 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr
> physaddr, vaddr addr,
>          return;
>      }
>
> -    env->sregs[SR_EAR] = addr;
> +    env->ear = addr;
>      if (access_type == MMU_INST_FETCH) {
>          if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
>              env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 9f2dcd82cd..62747b02f3 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -1809,7 +1809,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int
> flags)
>      qemu_fprintf(f, "rmsr=%" PRIx64 " resr=%" PRIx64 " rear=%" PRIx64 " "
>                   "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
>                   "rbtr=%" PRIx64 "\n",
> -                 env->msr, env->sregs[SR_ESR], env->sregs[SR_EAR],
> +                 env->msr, env->sregs[SR_ESR], env->ear,
>                   env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
>                   env->sregs[SR_BTR]);
>      qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
> @@ -1873,8 +1873,10 @@ void mb_tcg_init(void)
>          tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, pc), "rpc");
>      cpu_SR[SR_MSR] =
>          tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, msr),
> "rmsr");
> +    cpu_SR[SR_EAR] =
> +        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear),
> "rear");
>
> -    for (i = SR_MSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
> +    for (i = SR_EAR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
>          cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
>                            offsetof(CPUMBState, sregs[i]),
>                            special_regnames[i]);
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 9268 bytes --]

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

* Re: [PATCH v2 09/76] target/microblaze: Split out FSR from env->sregs
  2020-08-28 14:18 ` [PATCH v2 09/76] target/microblaze: Split out FSR " Richard Henderson
@ 2020-08-31 20:51   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 20:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 5041 bytes --]

Le ven. 28 août 2020 16:25, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> Continue eliminating the sregs array in favor of individual members.
> Does not correct the width of FSR, yet.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  target/microblaze/cpu.h          | 1 +
>  linux-user/microblaze/cpu_loop.c | 4 ++--
>  target/microblaze/gdbstub.c      | 4 ++--
>  target/microblaze/op_helper.c    | 8 ++++----
>  target/microblaze/translate.c    | 6 ++++--
>  5 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index 7d94af43ed..bcafef99b0 100644
> --- a/target/microblaze/cpu.h
> +++ b/target/microblaze/cpu.h
> @@ -240,6 +240,7 @@ struct CPUMBState {
>      uint64_t msr;
>      uint64_t ear;
>      uint64_t esr;
> +    uint64_t fsr;
>      uint64_t sregs[14];
>      float_status fp_status;
>      /* Stack protectors. Yes, it's a hw feature.  */
> diff --git a/linux-user/microblaze/cpu_loop.c
> b/linux-user/microblaze/cpu_loop.c
> index c10e3e0261..da5e98b784 100644
> --- a/linux-user/microblaze/cpu_loop.c
> +++ b/linux-user/microblaze/cpu_loop.c
> @@ -96,10 +96,10 @@ void cpu_loop(CPUMBState *env)
>                  case ESR_EC_FPU:
>                      info.si_signo = TARGET_SIGFPE;
>                      info.si_errno = 0;
> -                    if (env->sregs[SR_FSR] & FSR_IO) {
> +                    if (env->fsr & FSR_IO) {
>                          info.si_code = TARGET_FPE_FLTINV;
>                      }
> -                    if (env->sregs[SR_FSR] & FSR_DZ) {
> +                    if (env->fsr & FSR_DZ) {
>                          info.si_code = TARGET_FPE_FLTDIV;
>                      }
>                      info._sifields._sigfault._addr = 0;
> diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
> index 05e22f233d..2634ce49fc 100644
> --- a/target/microblaze/gdbstub.c
> +++ b/target/microblaze/gdbstub.c
> @@ -71,7 +71,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray
> *mem_buf, int n)
>          val = env->esr;
>          break;
>      case GDB_FSR:
> -        val = env->sregs[SR_FSR];
> +        val = env->fsr;
>          break;
>      case GDB_BTR:
>          val = env->sregs[SR_BTR];
> @@ -127,7 +127,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t
> *mem_buf, int n)
>          env->esr = tmp;
>          break;
>      case GDB_FSR:
> -        env->sregs[SR_FSR] = tmp;
> +        env->fsr = tmp;
>          break;
>      case GDB_BTR:
>          env->sregs[SR_BTR] = tmp;
> diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
> index f01cf9be64..ae57d45536 100644
> --- a/target/microblaze/op_helper.c
> +++ b/target/microblaze/op_helper.c
> @@ -175,19 +175,19 @@ static void update_fpu_flags(CPUMBState *env, int
> flags)
>      int raise = 0;
>
>      if (flags & float_flag_invalid) {
> -        env->sregs[SR_FSR] |= FSR_IO;
> +        env->fsr |= FSR_IO;
>          raise = 1;
>      }
>      if (flags & float_flag_divbyzero) {
> -        env->sregs[SR_FSR] |= FSR_DZ;
> +        env->fsr |= FSR_DZ;
>          raise = 1;
>      }
>      if (flags & float_flag_overflow) {
> -        env->sregs[SR_FSR] |= FSR_OF;
> +        env->fsr |= FSR_OF;
>          raise = 1;
>      }
>      if (flags & float_flag_underflow) {
> -        env->sregs[SR_FSR] |= FSR_UF;
> +        env->fsr |= FSR_UF;
>          raise = 1;
>      }
>      if (raise
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 411c7b6e49..c58c49ea8f 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -1810,7 +1810,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int
> flags)
>                   "debug=%x imm=%x iflags=%x fsr=%" PRIx64 " "
>                   "rbtr=%" PRIx64 "\n",
>                   env->msr, env->esr, env->ear,
> -                 env->debug, env->imm, env->iflags, env->sregs[SR_FSR],
> +                 env->debug, env->imm, env->iflags, env->fsr,
>                   env->sregs[SR_BTR]);
>      qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
>                   "eip=%d ie=%d\n",
> @@ -1877,8 +1877,10 @@ void mb_tcg_init(void)
>          tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, ear),
> "rear");
>      cpu_SR[SR_ESR] =
>          tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr),
> "resr");
> +    cpu_SR[SR_FSR] =
> +        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr),
> "rfsr");
>
> -    for (i = SR_ESR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
> +    for (i = SR_FSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
>          cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
>                            offsetof(CPUMBState, sregs[i]),
>                            special_regnames[i]);
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 6815 bytes --]

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

* Re: [PATCH v2 10/76] target/microblaze: Split out BTR from env->sregs
  2020-08-28 14:18 ` [PATCH v2 10/76] target/microblaze: Split out BTR " Richard Henderson
@ 2020-08-31 20:53   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 20:53 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 4172 bytes --]

Le ven. 28 août 2020 16:26, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> Continue eliminating the sregs array in favor of individual members.
> Does not correct the width of BTR, yet.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  target/microblaze/cpu.h       | 1 +
>  target/microblaze/gdbstub.c   | 4 ++--
>  target/microblaze/helper.c    | 4 ++--
>  target/microblaze/translate.c | 6 ++++--
>  4 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index bcafef99b0..deddb47abb 100644
> --- a/target/microblaze/cpu.h
> +++ b/target/microblaze/cpu.h
> @@ -241,6 +241,7 @@ struct CPUMBState {
>      uint64_t ear;
>      uint64_t esr;
>      uint64_t fsr;
> +    uint64_t btr;
>      uint64_t sregs[14];
>      float_status fp_status;
>      /* Stack protectors. Yes, it's a hw feature.  */
> diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
> index 2634ce49fc..cde8c169bf 100644
> --- a/target/microblaze/gdbstub.c
> +++ b/target/microblaze/gdbstub.c
> @@ -74,7 +74,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray
> *mem_buf, int n)
>          val = env->fsr;
>          break;
>      case GDB_BTR:
> -        val = env->sregs[SR_BTR];
> +        val = env->btr;
>          break;
>      case GDB_PVR0 ... GDB_PVR11:
>          /* PVR12 is intentionally skipped */
> @@ -130,7 +130,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t
> *mem_buf, int n)
>          env->fsr = tmp;
>          break;
>      case GDB_BTR:
> -        env->sregs[SR_BTR] = tmp;
> +        env->btr = tmp;
>          break;
>      case GDB_PVR0 ... GDB_PVR11:
>          /* PVR12 is intentionally skipped */
> diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
> index ea290be780..b240dc76f6 100644
> --- a/target/microblaze/helper.c
> +++ b/target/microblaze/helper.c
> @@ -132,7 +132,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              /* Exception breaks branch + dslot sequence?  */
>              if (env->iflags & D_FLAG) {
>                  env->esr |= 1 << 12 ;
> -                env->sregs[SR_BTR] = env->btarget;
> +                env->btr = env->btarget;
>              }
>
>              /* Disable the MMU.  */
> @@ -160,7 +160,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
>              if (env->iflags & D_FLAG) {
>                  D(qemu_log("D_FLAG set at exception bimm=%d\n",
> env->bimm));
>                  env->esr |= 1 << 12 ;
> -                env->sregs[SR_BTR] = env->btarget;
> +                env->btr = env->btarget;
>
>                  /* Reexecute the branch.  */
>                  env->regs[17] -= 4;
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index c58c49ea8f..469e1f103a 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -1811,7 +1811,7 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int
> flags)
>                   "rbtr=%" PRIx64 "\n",
>                   env->msr, env->esr, env->ear,
>                   env->debug, env->imm, env->iflags, env->fsr,
> -                 env->sregs[SR_BTR]);
> +                 env->btr);
>      qemu_fprintf(f, "btaken=%d btarget=%" PRIx64 " mode=%s(saved=%s) "
>                   "eip=%d ie=%d\n",
>                   env->btaken, env->btarget,
> @@ -1879,8 +1879,10 @@ void mb_tcg_init(void)
>          tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, esr),
> "resr");
>      cpu_SR[SR_FSR] =
>          tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, fsr),
> "rfsr");
> +    cpu_SR[SR_BTR] =
> +        tcg_global_mem_new_i64(cpu_env, offsetof(CPUMBState, btr),
> "rbtr");
>
> -    for (i = SR_FSR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
> +    for (i = SR_BTR + 1; i < ARRAY_SIZE(cpu_SR); i++) {
>          cpu_SR[i] = tcg_global_mem_new_i64(cpu_env,
>                            offsetof(CPUMBState, sregs[i]),
>                            special_regnames[i]);
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 5775 bytes --]

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

* Re: [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state
  2020-08-28 14:19 ` [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
@ 2020-08-31 21:08   ` Philippe Mathieu-Daudé
  2020-08-31 22:16     ` Richard Henderson
  0 siblings, 1 reply; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 21:08 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 3931 bytes --]

Hi Richard,

Le ven. 28 août 2020 16:46, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> Using lookup_symbol is quite slow; remove that.  Decode the
>

Can we add some runtime option to enable its use instead?

various bits of iflags; only show imm, btaken, btarget when
> they are relevant to iflags.  Improve formatting.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/microblaze/translate.c | 67 +++++++++++++++++++++--------------
>  1 file changed, 41 insertions(+), 26 deletions(-)
>
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 811c92d23b..3b63fd79e5 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -1818,41 +1818,56 @@ void mb_cpu_dump_state(CPUState *cs, FILE *f, int
> flags)
>  {
>      MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
>      CPUMBState *env = &cpu->env;
> +    uint32_t iflags;
>      int i;
>
> -    if (!env) {
> -        return;
> -    }
> -
> -    qemu_fprintf(f, "IN: PC=%x %s\n",
> -                 env->pc, lookup_symbol(env->pc));
> -    qemu_fprintf(f, "rmsr=%x resr=%x rear=%" PRIx64 " "
> -                 "imm=%x iflags=%x fsr=%x rbtr=%x\n",
> -                 env->msr, env->esr, env->ear,
> -                 env->imm, env->iflags, env->fsr, env->btr);
> -    qemu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s) eip=%d
> ie=%d\n",
> -                 env->btaken, env->btarget,
> +    qemu_fprintf(f, "pc=0x%08x msr=0x%05x mode=%s(saved=%s) eip=%d
> ie=%d\n",
> +                 env->pc, env->msr,
>                   (env->msr & MSR_UM) ? "user" : "kernel",
>                   (env->msr & MSR_UMS) ? "user" : "kernel",
>                   (bool)(env->msr & MSR_EIP),
>                   (bool)(env->msr & MSR_IE));
> -    for (i = 0; i < 12; i++) {
> -        qemu_fprintf(f, "rpvr%2.2d=%8.8x ", i, env->pvr.regs[i]);
> -        if ((i + 1) % 4 == 0) {
> -            qemu_fprintf(f, "\n");
> -        }
> +
> +    iflags = env->iflags;
> +    qemu_fprintf(f, "iflags: 0x%08x", iflags);
> +    if (iflags & IMM_FLAG) {
> +        qemu_fprintf(f, " IMM(0x%08x)", env->imm);
> +    }
> +    if (iflags & BIMM_FLAG) {
> +        qemu_fprintf(f, " BIMM");
> +    }
> +    if (iflags & D_FLAG) {
> +        qemu_fprintf(f, " D(btaken=%d btarget=0x%08x)",
> +                     env->btaken, env->btarget);
> +    }
> +    if (iflags & DRTI_FLAG) {
> +        qemu_fprintf(f, " DRTI");
> +    }
> +    if (iflags & DRTE_FLAG) {
> +        qemu_fprintf(f, " DRTE");
> +    }
> +    if (iflags & DRTB_FLAG) {
> +        qemu_fprintf(f, " DRTB");
> +    }
> +    if (iflags & ESR_ESS_FLAG) {
> +        qemu_fprintf(f, " ESR_ESS(0x%04x)", iflags & ESR_ESS_MASK);
> +    }
> +
> +    qemu_fprintf(f, "\nesr=0x%04x fsr=0x%02x btr=0x%08x edr=0x%x\n"
> +                 "ear=0x%016" PRIx64 " slr=0x%x shr=0x%x\n",
> +                 env->esr, env->fsr, env->btr, env->edr,
> +                 env->ear, env->slr, env->shr);
> +
> +    for (i = 0; i < 12; i++) {
> +        qemu_fprintf(f, "rpvr%-2d=%08x%c",
> +                     i, env->pvr.regs[i], i % 4 == 3 ? '\n' : ' ');
>      }
>
> -    /* Registers that aren't modeled are reported as 0 */
> -    qemu_fprintf(f, "redr=%x rpid=0 rzpr=0 rtlbx=0 rtlbsx=0 "
> -                    "rtlblo=0 rtlbhi=0\n", env->edr);
> -    qemu_fprintf(f, "slr=%x shr=%x\n", env->slr, env->shr);
>      for (i = 0; i < 32; i++) {
> -        qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
> -        if ((i + 1) % 4 == 0)
> -            qemu_fprintf(f, "\n");
> -        }
> -    qemu_fprintf(f, "\n\n");
> +        qemu_fprintf(f, "r%2.2d=%08x%c",
> +                     i, env->regs[i], i % 4 == 3 ? '\n' : ' ');
> +    }
> +    qemu_fprintf(f, "\n");
>  }
>
>  void mb_tcg_init(void)
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 5581 bytes --]

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

* Re: [PATCH v2 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE
  2020-08-28 14:19 ` [PATCH v2 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
@ 2020-08-31 21:09   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 21:09 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 2095 bytes --]

Le ven. 28 août 2020 16:42, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> There's no reason to define MSR_EE_FLAG; we can just use the
> original MSR_EE define.  Document the other flags copied into
> tb_flags with iflag to reserve those bits.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  target/microblaze/cpu.h       | 4 +++-
>  target/microblaze/translate.c | 4 ++--
>  2 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index 013858b8e0..594501e4e7 100644
> --- a/target/microblaze/cpu.h
> +++ b/target/microblaze/cpu.h
> @@ -254,7 +254,9 @@ struct CPUMBState {
>
>      /* Internal flags.  */
>  #define IMM_FLAG       4
> -#define MSR_EE_FLAG     (1 << 8)
> +/* MSR_EE               (1 << 8)  */
> +/* MSR_UM               (1 << 11) */
> +/* MSR_VM               (1 << 13) */
>  #define DRTI_FLAG      (1 << 16)
>  #define DRTE_FLAG      (1 << 17)
>  #define DRTB_FLAG      (1 << 18)
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 72541905ec..1f6731e0af 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -162,7 +162,7 @@ static void gen_goto_tb(DisasContext *dc, int n,
> target_ulong dest)
>   */
>  static bool trap_illegal(DisasContext *dc, bool cond)
>  {
> -    if (cond && (dc->tb_flags & MSR_EE_FLAG)
> +    if (cond && (dc->tb_flags & MSR_EE)
>          && dc->cpu->cfg.illegal_opcode_exception) {
>          gen_raise_hw_excp(dc, ESR_EC_ILLEGAL_OP);
>      }
> @@ -178,7 +178,7 @@ static bool trap_userspace(DisasContext *dc, bool cond)
>      int mem_index = cpu_mmu_index(&dc->cpu->env, false);
>      bool cond_user = cond && mem_index == MMU_USER_IDX;
>
> -    if (cond_user && (dc->tb_flags & MSR_EE_FLAG)) {
> +    if (cond_user && (dc->tb_flags & MSR_EE)) {
>          gen_raise_hw_excp(dc, ESR_EC_PRIVINSN);
>      }
>      return cond_user;
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 3309 bytes --]

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

* Re: [PATCH v2 23/76] target/microblaze: Rename env_* tcg variables to cpu_*
  2020-08-28 14:18 ` [PATCH v2 23/76] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
@ 2020-08-31 21:11   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 21:11 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 7761 bytes --]

Le ven. 28 août 2020 16:36, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> This is cpu_imm, cpu_btaken, cpu_iflags, cpu_res_addr and cpu_res_val.
> It is standard for these file-scope globals to begin with cpu_*.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  target/microblaze/translate.c | 54 +++++++++++++++++------------------
>  1 file changed, 27 insertions(+), 27 deletions(-)
>
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index ecfa6b86a4..9aa63ddcc5 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -56,12 +56,12 @@
>  static TCGv_i32 cpu_R[32];
>  static TCGv_i32 cpu_pc;
>  static TCGv_i32 cpu_msr;
> -static TCGv_i32 env_imm;
> -static TCGv_i32 env_btaken;
> +static TCGv_i32 cpu_imm;
> +static TCGv_i32 cpu_btaken;
>  static TCGv_i32 cpu_btarget;
> -static TCGv_i32 env_iflags;
> -static TCGv env_res_addr;
> -static TCGv_i32 env_res_val;
> +static TCGv_i32 cpu_iflags;
> +static TCGv cpu_res_addr;
> +static TCGv_i32 cpu_res_val;
>
>  #include "exec/gen-icount.h"
>
> @@ -107,7 +107,7 @@ static inline void t_sync_flags(DisasContext *dc)
>  {
>      /* Synch the tb dependent flags between translator and runtime.  */
>      if (dc->tb_flags != dc->synced_flags) {
> -        tcg_gen_movi_i32(env_iflags, dc->tb_flags);
> +        tcg_gen_movi_i32(cpu_iflags, dc->tb_flags);
>          dc->synced_flags = dc->tb_flags;
>      }
>  }
> @@ -222,10 +222,10 @@ static inline TCGv_i32 *dec_alu_op_b(DisasContext
> *dc)
>  {
>      if (dc->type_b) {
>          if (dc->tb_flags & IMM_FLAG)
> -            tcg_gen_ori_i32(env_imm, env_imm, dc->imm);
> +            tcg_gen_ori_i32(cpu_imm, cpu_imm, dc->imm);
>          else
> -            tcg_gen_movi_i32(env_imm, (int32_t)((int16_t)dc->imm));
> -        return &env_imm;
> +            tcg_gen_movi_i32(cpu_imm, (int32_t)((int16_t)dc->imm));
> +        return &cpu_imm;
>      } else
>          return &cpu_R[dc->rb];
>  }
> @@ -859,7 +859,7 @@ static inline void sync_jmpstate(DisasContext *dc)
>  {
>      if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
>          if (dc->jmp == JMP_DIRECT) {
> -            tcg_gen_movi_i32(env_btaken, 1);
> +            tcg_gen_movi_i32(cpu_btaken, 1);
>          }
>          dc->jmp = JMP_INDIRECT;
>          tcg_gen_movi_i32(cpu_btarget, dc->jmp_pc);
> @@ -869,7 +869,7 @@ static inline void sync_jmpstate(DisasContext *dc)
>  static void dec_imm(DisasContext *dc)
>  {
>      LOG_DIS("imm %x\n", dc->imm << 16);
> -    tcg_gen_movi_i32(env_imm, (dc->imm << 16));
> +    tcg_gen_movi_i32(cpu_imm, (dc->imm << 16));
>      dc->tb_flags |= IMM_FLAG;
>      dc->clear_imm = 0;
>  }
> @@ -1040,8 +1040,8 @@ static void dec_load(DisasContext *dc)
>      }
>
>      if (ex) {
> -        tcg_gen_mov_tl(env_res_addr, addr);
> -        tcg_gen_mov_i32(env_res_val, v);
> +        tcg_gen_mov_tl(cpu_res_addr, addr);
> +        tcg_gen_mov_i32(cpu_res_val, v);
>      }
>      if (dc->rd) {
>          tcg_gen_mov_i32(cpu_R[dc->rd], v);
> @@ -1103,7 +1103,7 @@ static void dec_store(DisasContext *dc)
>
>          write_carryi(dc, 1);
>          swx_skip = gen_new_label();
> -        tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, addr, swx_skip);
> +        tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_skip);
>
>          /*
>           * Compare the value loaded at lwx with current contents of
> @@ -1111,11 +1111,11 @@ static void dec_store(DisasContext *dc)
>           */
>          tval = tcg_temp_new_i32();
>
> -        tcg_gen_atomic_cmpxchg_i32(tval, addr, env_res_val,
> +        tcg_gen_atomic_cmpxchg_i32(tval, addr, cpu_res_val,
>                                     cpu_R[dc->rd], mem_index,
>                                     mop);
>
> -        tcg_gen_brcond_i32(TCG_COND_NE, env_res_val, tval, swx_skip);
> +        tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_skip);
>          write_carryi(dc, 0);
>          tcg_temp_free_i32(tval);
>      }
> @@ -1204,7 +1204,7 @@ static void eval_cond_jmp(DisasContext *dc, TCGv_i32
> pc_true, TCGv_i32 pc_false)
>      TCGv_i32 zero = tcg_const_i32(0);
>
>      tcg_gen_movcond_i32(TCG_COND_NE, cpu_pc,
> -                        env_btaken, zero,
> +                        cpu_btaken, zero,
>                          pc_true, pc_false);
>
>      tcg_temp_free_i32(zero);
> @@ -1245,7 +1245,7 @@ static void dec_bcc(DisasContext *dc)
>          dc->jmp = JMP_INDIRECT;
>          tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
>      }
> -    eval_cc(dc, cc, env_btaken, cpu_R[dc->ra]);
> +    eval_cc(dc, cc, cpu_btaken, cpu_R[dc->ra]);
>  }
>
>  static void dec_br(DisasContext *dc)
> @@ -1311,7 +1311,7 @@ static void dec_br(DisasContext *dc)
>
>      dc->jmp = JMP_INDIRECT;
>      if (abs) {
> -        tcg_gen_movi_i32(env_btaken, 1);
> +        tcg_gen_movi_i32(cpu_btaken, 1);
>          tcg_gen_mov_i32(cpu_btarget, *(dec_alu_op_b(dc)));
>          if (link && !dslot) {
>              if (!(dc->tb_flags & IMM_FLAG) &&
> @@ -1330,7 +1330,7 @@ static void dec_br(DisasContext *dc)
>              dc->jmp = JMP_DIRECT;
>              dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
>          } else {
> -            tcg_gen_movi_i32(env_btaken, 1);
> +            tcg_gen_movi_i32(cpu_btaken, 1);
>              tcg_gen_addi_i32(cpu_btarget, *dec_alu_op_b(dc), dc->pc);
>          }
>      }
> @@ -1419,7 +1419,7 @@ static void dec_rts(DisasContext *dc)
>          LOG_DIS("rts ir=%x\n", dc->ir);
>
>      dc->jmp = JMP_INDIRECT;
> -    tcg_gen_movi_i32(env_btaken, 1);
> +    tcg_gen_movi_i32(cpu_btaken, 1);
>      tcg_gen_add_i32(cpu_btarget, cpu_R[dc->ra], *dec_alu_op_b(dc));
>  }
>
> @@ -1722,7 +1722,7 @@ void gen_intermediate_code(CPUState *cs,
> TranslationBlock *tb, int max_insns)
>                      TCGLabel *l1 = gen_new_label();
>                      t_sync_flags(dc);
>                      /* Conditional jmp.  */
> -                    tcg_gen_brcondi_i32(TCG_COND_NE, env_btaken, 0, l1);
> +                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_btaken, 0, l1);
>                      gen_goto_tb(dc, 1, dc->pc);
>                      gen_set_label(l1);
>                      gen_goto_tb(dc, 0, dc->jmp_pc);
> @@ -1848,22 +1848,22 @@ void mb_tcg_init(void)
>  {
>      int i;
>
> -    env_iflags = tcg_global_mem_new_i32(cpu_env,
> +    cpu_iflags = tcg_global_mem_new_i32(cpu_env,
>                      offsetof(CPUMBState, iflags),
>                      "iflags");
> -    env_imm = tcg_global_mem_new_i32(cpu_env,
> +    cpu_imm = tcg_global_mem_new_i32(cpu_env,
>                      offsetof(CPUMBState, imm),
>                      "imm");
>      cpu_btarget = tcg_global_mem_new_i32(cpu_env,
>                       offsetof(CPUMBState, btarget),
>                       "btarget");
> -    env_btaken = tcg_global_mem_new_i32(cpu_env,
> +    cpu_btaken = tcg_global_mem_new_i32(cpu_env,
>                       offsetof(CPUMBState, btaken),
>                       "btaken");
> -    env_res_addr = tcg_global_mem_new(cpu_env,
> +    cpu_res_addr = tcg_global_mem_new(cpu_env,
>                       offsetof(CPUMBState, res_addr),
>                       "res_addr");
> -    env_res_val = tcg_global_mem_new_i32(cpu_env,
> +    cpu_res_val = tcg_global_mem_new_i32(cpu_env,
>                       offsetof(CPUMBState, res_val),
>                       "res_val");
>      for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 9980 bytes --]

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

* Re: [PATCH v2 32/76] target/microblaze: Remove empty D macros
  2020-08-28 14:18 ` [PATCH v2 32/76] target/microblaze: Remove empty D macros Richard Henderson
@ 2020-08-31 21:14   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 21:14 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 3154 bytes --]

Le ven. 28 août 2020 16:32, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> This is never used in op_helper.c and translate.c.  There are
> two trivial uses in helper.c which can be improved by always
> logging MMU_EXCP to CPU_LOG_INT.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
>  target/microblaze/helper.c    | 11 ++++-------
>  target/microblaze/op_helper.c |  2 --
>  target/microblaze/translate.c |  2 --
>  3 files changed, 4 insertions(+), 11 deletions(-)
>
> diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
> index 9a95456401..f8e2ca12a9 100644
> --- a/target/microblaze/helper.c
> +++ b/target/microblaze/helper.c
> @@ -24,8 +24,6 @@
>  #include "qemu/host-utils.h"
>  #include "exec/log.h"
>
> -#define D(x)
> -
>  #if defined(CONFIG_USER_ONLY)
>
>  void mb_cpu_do_interrupt(CPUState *cs)
> @@ -155,10 +153,13 @@ void mb_cpu_do_interrupt(CPUState *cs)
>          case EXCP_MMU:
>              env->regs[17] = env->pc;
>
> +            qemu_log_mask(CPU_LOG_INT,
> +                          "MMU exception at pc=%x iflags=%x ear=%" PRIx64
> "\n",
> +                          env->pc, env->iflags, env->ear);
> +
>              env->esr &= ~(1 << 12);
>              /* Exception breaks branch + dslot sequence?  */
>              if (env->iflags & D_FLAG) {
> -                D(qemu_log("D_FLAG set at exception bimm=%d\n",
> env->bimm));
>                  env->esr |= 1 << 12 ;
>                  env->btr = env->btarget;
>
> @@ -166,14 +167,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
>                  env->regs[17] -= 4;
>                  /* was the branch immprefixed?.  */
>                  if (env->bimm) {
> -                    qemu_log_mask(CPU_LOG_INT,
> -                                  "bimm exception at pc=%x iflags=%x\n",
> -                                  env->pc, env->iflags);
>                      env->regs[17] -= 4;
>                      log_cpu_state_mask(CPU_LOG_INT, cs, 0);
>                  }
>              } else if (env->iflags & IMM_FLAG) {
> -                D(qemu_log("IMM_FLAG set at exception\n"));
>                  env->regs[17] -= 4;
>              }
>
> diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
> index d79202c3f8..decdca0fd8 100644
> --- a/target/microblaze/op_helper.c
> +++ b/target/microblaze/op_helper.c
> @@ -26,8 +26,6 @@
>  #include "exec/cpu_ldst.h"
>  #include "fpu/softfloat.h"
>
> -#define D(x)
> -
>  void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
>  {
>      int test = ctrl & STREAM_TEST;
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 6757720776..860859324a 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -41,8 +41,6 @@
>  #  define LOG_DIS(...) do { } while (0)
>  #endif
>
> -#define D(x)
> -
>  #define EXTRACT_FIELD(src, start, end) \
>              (((src) >> start) & ((1 << (end - start + 1)) - 1))
>
> --
> 2.25.1
>
>
>

[-- Attachment #2: Type: text/html, Size: 4646 bytes --]

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

* Re: [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state
  2020-08-31 21:08   ` Philippe Mathieu-Daudé
@ 2020-08-31 22:16     ` Richard Henderson
  2020-08-31 22:25       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 92+ messages in thread
From: Richard Henderson @ 2020-08-31 22:16 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

On 8/31/20 2:08 PM, Philippe Mathieu-Daudé wrote:
> Hi Richard, 
> 
> Le ven. 28 août 2020 16:46, Richard Henderson <richard.henderson@linaro.org
> <mailto:richard.henderson@linaro.org>> a écrit :
> 
>     Using lookup_symbol is quite slow; remove that.  Decode the
> 
> 
> Can we add some runtime option to enable its use instead?

We do the lookup with -d in_asm.
Do we really need it with -d cpu as well?

The -d cpu can be called many millions of times more than -d in_asm, and the
two are relatively easy to correlate.


r~


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

* Re: [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state
  2020-08-31 22:16     ` Richard Henderson
@ 2020-08-31 22:25       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 92+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-08-31 22:25 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Edgar E. Iglesias, qemu-devel@nongnu.org Developers

[-- Attachment #1: Type: text/plain, Size: 746 bytes --]

Le mar. 1 sept. 2020 00:16, Richard Henderson <richard.henderson@linaro.org>
a écrit :

> On 8/31/20 2:08 PM, Philippe Mathieu-Daudé wrote:
> > Hi Richard,
> >
> > Le ven. 28 août 2020 16:46, Richard Henderson <
> richard.henderson@linaro.org
> > <mailto:richard.henderson@linaro.org>> a écrit :
> >
> >     Using lookup_symbol is quite slow; remove that.  Decode the
> >
> >
> > Can we add some runtime option to enable its use instead?
>
> We do the lookup with -d in_asm.
> Do we really need it with -d cpu as well?
>
> The -d cpu can be called many millions of times more than -d in_asm, and
> the
> two are relatively easy to correlate.
>

Ah I missed that. This is fine then!

Thanks,

Phil.


>
> r~
>

[-- Attachment #2: Type: text/html, Size: 1595 bytes --]

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

end of thread, other threads:[~2020-08-31 22:26 UTC | newest]

Thread overview: 92+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-28 14:18 [PATCH v2 00/76] target/microblaze improvements Richard Henderson
2020-08-28 14:18 ` [PATCH v2 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
2020-08-31 17:32   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 02/76] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
2020-08-31 17:31   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 03/76] tests/tcg: Do not require FE_* exception bits Richard Henderson
2020-08-31 17:30   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 04/76] target/microblaze: Tidy gdbstub Richard Henderson
2020-08-28 14:18 ` [PATCH v2 05/76] target/microblaze: Split out PC from env->sregs Richard Henderson
2020-08-28 14:18 ` [PATCH v2 06/76] target/microblaze: Split out MSR " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 07/76] target/microblaze: Split out EAR " Richard Henderson
2020-08-31 20:50   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 08/76] target/microblaze: Split out ESR " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 09/76] target/microblaze: Split out FSR " Richard Henderson
2020-08-31 20:51   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 10/76] target/microblaze: Split out BTR " Richard Henderson
2020-08-31 20:53   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 11/76] target/microblaze: Split out EDR " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 12/76] target/microblaze: Split the cpu_SR array Richard Henderson
2020-08-28 14:18 ` [PATCH v2 13/76] target/microblaze: Fix width of PC and BTARGET Richard Henderson
2020-08-28 14:18 ` [PATCH v2 14/76] target/microblaze: Fix width of MSR Richard Henderson
2020-08-28 14:18 ` [PATCH v2 15/76] target/microblaze: Fix width of ESR Richard Henderson
2020-08-28 14:18 ` [PATCH v2 16/76] target/microblaze: Fix width of FSR Richard Henderson
2020-08-28 14:18 ` [PATCH v2 17/76] target/microblaze: Fix width of BTR Richard Henderson
2020-08-28 14:18 ` [PATCH v2 18/76] target/microblaze: Fix width of EDR Richard Henderson
2020-08-28 14:18 ` [PATCH v2 19/76] target/microblaze: Remove cpu_ear Richard Henderson
2020-08-28 14:18 ` [PATCH v2 20/76] target/microblaze: Tidy raising of exceptions Richard Henderson
2020-08-28 14:18 ` [PATCH v2 21/76] target/microblaze: Mark raise_exception as noreturn Richard Henderson
2020-08-28 14:18 ` [PATCH v2 22/76] target/microblaze: Remove helper_debug and env->debug Richard Henderson
2020-08-28 14:18 ` [PATCH v2 23/76] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
2020-08-31 21:11   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 24/76] target/microblaze: Tidy mb_tcg_init Richard Henderson
2020-08-28 14:18 ` [PATCH v2 25/76] target/microblaze: Split out MSR[C] to its own variable Richard Henderson
2020-08-28 14:18 ` [PATCH v2 26/76] target/microblaze: Use DISAS_NORETURN Richard Henderson
2020-08-28 14:18 ` [PATCH v2 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
2020-08-31 13:54   ` Edgar E. Iglesias
2020-08-31 14:55     ` Richard Henderson
2020-08-28 14:18 ` [PATCH v2 28/76] target/microblaze: Convert to DisasContextBase Richard Henderson
2020-08-28 14:18 ` [PATCH v2 29/76] target/microblaze: Convert to translator_loop Richard Henderson
2020-08-28 14:18 ` [PATCH v2 30/76] target/microblaze: Remove SIM_COMPAT Richard Henderson
2020-08-28 14:18 ` [PATCH v2 31/76] target/microblaze: Remove DISAS_GNU Richard Henderson
2020-08-28 14:18 ` [PATCH v2 32/76] target/microblaze: Remove empty D macros Richard Henderson
2020-08-31 21:14   ` Philippe Mathieu-Daudé
2020-08-28 14:18 ` [PATCH v2 33/76] target/microblaze: Remove LOG_DIS Richard Henderson
2020-08-28 14:18 ` [PATCH v2 34/76] target/microblaze: Ensure imm constant is always available Richard Henderson
2020-08-28 14:18 ` [PATCH v2 35/76] target/microblaze: Add decodetree infrastructure Richard Henderson
2020-08-28 14:18 ` [PATCH v2 36/76] target/microblaze: Convert dec_add to decodetree Richard Henderson
2020-08-28 14:18 ` [PATCH v2 37/76] target/microblaze: Convert dec_sub " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 38/76] target/microblaze: Implement cmp and cmpu inline Richard Henderson
2020-08-28 14:18 ` [PATCH v2 39/76] target/microblaze: Convert dec_pattern to decodetree Richard Henderson
2020-08-28 14:18 ` [PATCH v2 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 41/76] target/microblaze: Convert dec_mul " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 42/76] target/microblaze: Convert dec_div " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 43/76] target/microblaze: Unwind properly when raising divide-by-zero Richard Henderson
2020-08-28 14:18 ` [PATCH v2 44/76] target/microblaze: Convert dec_bit to decodetree Richard Henderson
2020-08-28 14:18 ` [PATCH v2 45/76] target/microblaze: Convert dec_barrel " Richard Henderson
2020-08-28 14:18 ` [PATCH v2 46/76] target/microblaze: Convert dec_imm " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 47/76] target/microblaze: Convert dec_fpu " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 48/76] target/microblaze: Fix cpu unwind for fpu exceptions Richard Henderson
2020-08-28 14:19 ` [PATCH v2 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG Richard Henderson
2020-08-28 14:19 ` [PATCH v2 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
2020-08-31 21:09   ` Philippe Mathieu-Daudé
2020-08-28 14:19 ` [PATCH v2 51/76] target/microblaze: Cache mem_index in DisasContext Richard Henderson
2020-08-28 14:19 ` [PATCH v2 52/76] target/microblaze: Fix cpu unwind for stackprot Richard Henderson
2020-08-28 14:19 ` [PATCH v2 53/76] target/microblaze: Convert dec_load and dec_store to decodetree Richard Henderson
2020-08-28 14:19 ` [PATCH v2 54/76] target/microblaze: Assert no overlap in flags making up tb_flags Richard Henderson
2020-08-28 14:19 ` [PATCH v2 55/76] target/microblaze: Move bimm to BIMM_FLAG Richard Henderson
2020-08-28 14:19 ` [PATCH v2 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed Richard Henderson
2020-08-28 14:19 ` [PATCH v2 57/76] target/microblaze: Store "current" iflags in insn_start Richard Henderson
2020-08-28 14:19 ` [PATCH v2 58/76] tcg: Add tcg_get_insn_start_param Richard Henderson
2020-08-28 14:19 ` [PATCH v2 59/76] target/microblaze: Use cc->do_unaligned_access Richard Henderson
2020-08-28 14:19 ` [PATCH v2 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set Richard Henderson
2020-08-28 14:19 ` [PATCH v2 61/76] target/microblaze: Replace delayed_branch " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 62/76] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
2020-08-31 21:08   ` Philippe Mathieu-Daudé
2020-08-31 22:16     ` Richard Henderson
2020-08-31 22:25       ` Philippe Mathieu-Daudé
2020-08-28 14:19 ` [PATCH v2 63/76] target/microblaze: Convert brk and brki to decodetree Richard Henderson
2020-08-28 14:19 ` [PATCH v2 64/76] target/microblaze: Convert mbar " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 65/76] target/microblaze: Reorganize branching Richard Henderson
2020-08-28 14:19 ` [PATCH v2 66/76] target/microblaze: Convert dec_br to decodetree Richard Henderson
2020-08-28 14:19 ` [PATCH v2 67/76] target/microblaze: Convert dec_bcc " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 68/76] target/microblaze: Convert dec_rts " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte Richard Henderson
2020-08-28 14:19 ` [PATCH v2 70/76] target/microblaze: Convert msrclr, msrset to decodetree Richard Henderson
2020-08-28 14:19 ` [PATCH v2 71/76] target/microblaze: Convert dec_msr " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 72/76] target/microblaze: Convert dec_stream " Richard Henderson
2020-08-28 14:19 ` [PATCH v2 73/76] target/microblaze: Remove last of old decoder Richard Henderson
2020-08-28 14:19 ` [PATCH v2 74/76] target/microblaze: Remove cpu_R[0] Richard Henderson
2020-08-28 14:19 ` [PATCH v2 75/76] target/microblaze: Add flags markup to some helpers Richard Henderson
2020-08-28 14:19 ` [PATCH v2 76/76] target/microblaze: Reduce linux-user address space to 32-bit Richard Henderson
2020-08-31 14:14 ` [PATCH v2 00/76] target/microblaze improvements Edgar E. Iglesias

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.