* [PULL 01/76] tests/tcg: Add microblaze to arches filter
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 02/76] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
` (77 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Not attempting to use a single cross-compiler for both
big-endian and little-endian at this time.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 02/76] tests/tcg: Do not require FE_TOWARDZERO
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
2020-08-31 16:04 ` [PULL 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 03/76] tests/tcg: Do not require FE_* exception bits Richard Henderson
` (76 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
This is optional in ISO C, and not all cpus provide it.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 03/76] tests/tcg: Do not require FE_* exception bits
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
2020-08-31 16:04 ` [PULL 01/76] tests/tcg: Add microblaze to arches filter Richard Henderson
2020-08-31 16:04 ` [PULL 02/76] tests/tcg: Do not require FE_TOWARDZERO Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 04/76] target/microblaze: Tidy gdbstub Richard Henderson
` (75 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Define anything that is missing as 0, so that flags & FE_FOO
is false for any missing FOO.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 04/76] target/microblaze: Tidy gdbstub
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (2 preceding siblings ...)
2020-08-31 16:04 ` [PULL 03/76] tests/tcg: Do not require FE_* exception bits Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 05/76] target/microblaze: Split out PC from env->sregs Richard Henderson
` (74 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 05/76] target/microblaze: Split out PC from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (3 preceding siblings ...)
2020-08-31 16:04 ` [PULL 04/76] target/microblaze: Tidy gdbstub Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 06/76] target/microblaze: Split out MSR " Richard Henderson
` (73 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Begin eliminating the sregs array in favor of individual members.
Does not correct the width of pc, yet.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 06/76] target/microblaze: Split out MSR from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (4 preceding siblings ...)
2020-08-31 16:04 ` [PULL 05/76] target/microblaze: Split out PC from env->sregs Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 07/76] target/microblaze: Split out EAR " Richard Henderson
` (72 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Continue eliminating the sregs array in favor of individual members.
Does not correct the width of MSR, yet.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 07/76] target/microblaze: Split out EAR from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (5 preceding siblings ...)
2020-08-31 16:04 ` [PULL 06/76] target/microblaze: Split out MSR " Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 08/76] target/microblaze: Split out ESR " Richard Henderson
` (71 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Continue eliminating the sregs array in favor of individual members.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 08/76] target/microblaze: Split out ESR from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (6 preceding siblings ...)
2020-08-31 16:04 ` [PULL 07/76] target/microblaze: Split out EAR " Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 09/76] target/microblaze: Split out FSR " Richard Henderson
` (70 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Continue eliminating the sregs array in favor of individual members.
Does not correct the width of ESR, yet.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 09/76] target/microblaze: Split out FSR from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (7 preceding siblings ...)
2020-08-31 16:04 ` [PULL 08/76] target/microblaze: Split out ESR " Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 10/76] target/microblaze: Split out BTR " Richard Henderson
` (69 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Continue eliminating the sregs array in favor of individual members.
Does not correct the width of FSR, yet.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 10/76] target/microblaze: Split out BTR from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (8 preceding siblings ...)
2020-08-31 16:04 ` [PULL 09/76] target/microblaze: Split out FSR " Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 11/76] target/microblaze: Split out EDR " Richard Henderson
` (68 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Continue eliminating the sregs array in favor of individual members.
Does not correct the width of BTR, yet.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 11/76] target/microblaze: Split out EDR from env->sregs
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (9 preceding siblings ...)
2020-08-31 16:04 ` [PULL 10/76] target/microblaze: Split out BTR " Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 12/76] target/microblaze: Split the cpu_SR array Richard Henderson
` (67 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Finish eliminating the sregs array in favor of individual members.
Does not correct the width of EDR, yet.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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 69936dcd45..58b3f4ef4d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1038,9 +1038,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] 80+ messages in thread
* [PULL 12/76] target/microblaze: Split the cpu_SR array
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (10 preceding siblings ...)
2020-08-31 16:04 ` [PULL 11/76] target/microblaze: Split out EDR " Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 13/76] target/microblaze: Fix width of PC and BTARGET Richard Henderson
` (66 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Similar to splitting the sregs array, this will allow further
fixes and cleanups.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 13/76] target/microblaze: Fix width of PC and BTARGET
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (11 preceding siblings ...)
2020-08-31 16:04 ` [PULL 12/76] target/microblaze: Split the cpu_SR array Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:04 ` [PULL 14/76] target/microblaze: Fix width of MSR Richard Henderson
` (65 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 14/76] target/microblaze: Fix width of MSR
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (12 preceding siblings ...)
2020-08-31 16:04 ` [PULL 13/76] target/microblaze: Fix width of PC and BTARGET Richard Henderson
@ 2020-08-31 16:04 ` Richard Henderson
2020-08-31 16:05 ` [PULL 15/76] target/microblaze: Fix width of ESR Richard Henderson
` (64 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
The machine status register is only 32-bits wide.
Do not use a 64-bit type to represent it.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 15/76] target/microblaze: Fix width of ESR
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (13 preceding siblings ...)
2020-08-31 16:04 ` [PULL 14/76] target/microblaze: Fix width of MSR Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 16/76] target/microblaze: Fix width of FSR Richard Henderson
` (63 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
The exception status register is only 32-bits wide.
Do not use a 64-bit type to represent it.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 16/76] target/microblaze: Fix width of FSR
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (14 preceding siblings ...)
2020-08-31 16:05 ` [PULL 15/76] target/microblaze: Fix width of ESR Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 17/76] target/microblaze: Fix width of BTR Richard Henderson
` (62 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 17/76] target/microblaze: Fix width of BTR
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (15 preceding siblings ...)
2020-08-31 16:05 ` [PULL 16/76] target/microblaze: Fix width of FSR Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 18/76] target/microblaze: Fix width of EDR Richard Henderson
` (61 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 18/76] target/microblaze: Fix width of EDR
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (16 preceding siblings ...)
2020-08-31 16:05 ` [PULL 17/76] target/microblaze: Fix width of BTR Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 19/76] target/microblaze: Remove cpu_ear Richard Henderson
` (60 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 19/76] target/microblaze: Remove cpu_ear
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (17 preceding siblings ...)
2020-08-31 16:05 ` [PULL 18/76] target/microblaze: Fix width of EDR Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 20/76] target/microblaze: Tidy raising of exceptions Richard Henderson
` (59 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 20/76] target/microblaze: Tidy raising of exceptions
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (18 preceding siblings ...)
2020-08-31 16:05 ` [PULL 19/76] target/microblaze: Remove cpu_ear Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 21/76] target/microblaze: Mark raise_exception as noreturn Richard Henderson
` (58 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 21/76] target/microblaze: Mark raise_exception as noreturn
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (19 preceding siblings ...)
2020-08-31 16:05 ` [PULL 20/76] target/microblaze: Tidy raising of exceptions Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 22/76] target/microblaze: Remove helper_debug and env->debug Richard Henderson
` (57 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
This will allow tcg to remove any dead code that might
follow an exception.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 22/76] target/microblaze: Remove helper_debug and env->debug
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (20 preceding siblings ...)
2020-08-31 16:05 ` [PULL 21/76] target/microblaze: Mark raise_exception as noreturn Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 23/76] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
` (56 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
This is not used, and seems redundant with -d cpu.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 23/76] target/microblaze: Rename env_* tcg variables to cpu_*
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (21 preceding siblings ...)
2020-08-31 16:05 ` [PULL 22/76] target/microblaze: Remove helper_debug and env->debug Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 24/76] target/microblaze: Tidy mb_tcg_init Richard Henderson
` (55 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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_*.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 24/76] target/microblaze: Tidy mb_tcg_init
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (22 preceding siblings ...)
2020-08-31 16:05 ` [PULL 23/76] target/microblaze: Rename env_* tcg variables to cpu_* Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 25/76] target/microblaze: Split out MSR[C] to its own variable Richard Henderson
` (54 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 25/76] target/microblaze: Split out MSR[C] to its own variable
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (23 preceding siblings ...)
2020-08-31 16:05 ` [PULL 24/76] target/microblaze: Tidy mb_tcg_init Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 26/76] target/microblaze: Use DISAS_NORETURN Richard Henderson
` (53 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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 58b3f4ef4d..04c28cbb9e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1039,7 +1039,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] 80+ messages in thread
* [PULL 26/76] target/microblaze: Use DISAS_NORETURN
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (24 preceding siblings ...)
2020-08-31 16:05 ` [PULL 25/76] target/microblaze: Split out MSR[C] to its own variable Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
` (52 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (25 preceding siblings ...)
2020-08-31 16:05 ` [PULL 26/76] target/microblaze: Use DISAS_NORETURN Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 28/76] target/microblaze: Convert to DisasContextBase Richard Henderson
` (51 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Do not use goto_tb if we're single-stepping.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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..2e753fa621 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_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);
--
2.25.1
^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PULL 28/76] target/microblaze: Convert to DisasContextBase
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (26 preceding siblings ...)
2020-08-31 16:05 ` [PULL 27/76] target/microblaze: Check singlestep_enabled in gen_goto_tb Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 29/76] target/microblaze: Convert to translator_loop Richard Henderson
` (50 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Part one of conversion to the generic translator_loop is to
use the DisasContextBase and the members therein.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/microblaze/translate.c | 102 +++++++++++++++++-----------------
1 file changed, 51 insertions(+), 51 deletions(-)
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 2e753fa621..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,7 +137,7 @@ 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_i32(cpu_pc, dest);
gen_helper_raise_exception(cpu_env, tmp);
@@ -148,12 +145,12 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
} 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] 80+ messages in thread
* [PULL 29/76] target/microblaze: Convert to translator_loop
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (27 preceding siblings ...)
2020-08-31 16:05 ` [PULL 28/76] target/microblaze: Convert to DisasContextBase Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 30/76] target/microblaze: Remove SIM_COMPAT Richard Henderson
` (49 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Finish the conversion to the generic translator_loop.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 30/76] target/microblaze: Remove SIM_COMPAT
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (28 preceding siblings ...)
2020-08-31 16:05 ` [PULL 29/76] target/microblaze: Convert to translator_loop Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 31/76] target/microblaze: Remove DISAS_GNU Richard Henderson
` (48 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 31/76] target/microblaze: Remove DISAS_GNU
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (29 preceding siblings ...)
2020-08-31 16:05 ` [PULL 30/76] target/microblaze: Remove SIM_COMPAT Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 32/76] target/microblaze: Remove empty D macros Richard Henderson
` (47 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
This is never used.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 32/76] target/microblaze: Remove empty D macros
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (30 preceding siblings ...)
2020-08-31 16:05 ` [PULL 31/76] target/microblaze: Remove DISAS_GNU Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 33/76] target/microblaze: Remove LOG_DIS Richard Henderson
` (46 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 33/76] target/microblaze: Remove LOG_DIS
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (31 preceding siblings ...)
2020-08-31 16:05 ` [PULL 32/76] target/microblaze: Remove empty D macros Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 34/76] target/microblaze: Ensure imm constant is always available Richard Henderson
` (45 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Also remove the related defines, DISAS_MB and DEBUG_DISAS.
Rely on print_insn_microblaze.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 34/76] target/microblaze: Ensure imm constant is always available
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (32 preceding siblings ...)
2020-08-31 16:05 ` [PULL 33/76] target/microblaze: Remove LOG_DIS Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 35/76] target/microblaze: Add decodetree infrastructure Richard Henderson
` (44 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 35/76] target/microblaze: Add decodetree infrastructure
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (33 preceding siblings ...)
2020-08-31 16:05 ` [PULL 34/76] target/microblaze: Ensure imm constant is always available Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 36/76] target/microblaze: Convert dec_add to decodetree Richard Henderson
` (43 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
The new interface is a stub that recognizes no instructions.
It falls back to the old decoder for all instructions.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 36/76] target/microblaze: Convert dec_add to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (34 preceding siblings ...)
2020-08-31 16:05 ` [PULL 35/76] target/microblaze: Add decodetree infrastructure Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 37/76] target/microblaze: Convert dec_sub " Richard Henderson
` (42 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 37/76] target/microblaze: Convert dec_sub to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (35 preceding siblings ...)
2020-08-31 16:05 ` [PULL 36/76] target/microblaze: Convert dec_add to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 38/76] target/microblaze: Implement cmp and cmpu inline Richard Henderson
` (41 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Use tcg_gen_add2_i32 for computing carry.
This removes the last use of helper_carry, so remove that.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 38/76] target/microblaze: Implement cmp and cmpu inline
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (36 preceding siblings ...)
2020-08-31 16:05 ` [PULL 37/76] target/microblaze: Convert dec_sub " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 39/76] target/microblaze: Convert dec_pattern to decodetree Richard Henderson
` (40 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
These are simple enough operations; we do not need to
call an out-of-line helper.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 39/76] target/microblaze: Convert dec_pattern to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (37 preceding siblings ...)
2020-08-31 16:05 ` [PULL 38/76] target/microblaze: Implement cmp and cmpu inline Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor " Richard Henderson
` (39 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (38 preceding siblings ...)
2020-08-31 16:05 ` [PULL 39/76] target/microblaze: Convert dec_pattern to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 41/76] target/microblaze: Convert dec_mul " Richard Henderson
` (38 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 41/76] target/microblaze: Convert dec_mul to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (39 preceding siblings ...)
2020-08-31 16:05 ` [PULL 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 42/76] target/microblaze: Convert dec_div " Richard Henderson
` (37 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 42/76] target/microblaze: Convert dec_div to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (40 preceding siblings ...)
2020-08-31 16:05 ` [PULL 41/76] target/microblaze: Convert dec_mul " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 43/76] target/microblaze: Unwind properly when raising divide-by-zero Richard Henderson
` (36 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 43/76] target/microblaze: Unwind properly when raising divide-by-zero
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (41 preceding siblings ...)
2020-08-31 16:05 ` [PULL 42/76] target/microblaze: Convert dec_div " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 44/76] target/microblaze: Convert dec_bit to decodetree Richard Henderson
` (35 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Restore the correct pc when raising divide-by-zero. Also, the
MSR[DZO] bit is sticky -- it is not cleared with a successful divide.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 44/76] target/microblaze: Convert dec_bit to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (42 preceding siblings ...)
2020-08-31 16:05 ` [PULL 43/76] target/microblaze: Unwind properly when raising divide-by-zero Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 45/76] target/microblaze: Convert dec_barrel " Richard Henderson
` (34 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 45/76] target/microblaze: Convert dec_barrel to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (43 preceding siblings ...)
2020-08-31 16:05 ` [PULL 44/76] target/microblaze: Convert dec_bit to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 46/76] target/microblaze: Convert dec_imm " Richard Henderson
` (33 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 46/76] target/microblaze: Convert dec_imm to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (44 preceding siblings ...)
2020-08-31 16:05 ` [PULL 45/76] target/microblaze: Convert dec_barrel " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 47/76] target/microblaze: Convert dec_fpu " Richard Henderson
` (32 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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 | 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] 80+ messages in thread
* [PULL 47/76] target/microblaze: Convert dec_fpu to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (45 preceding siblings ...)
2020-08-31 16:05 ` [PULL 46/76] target/microblaze: Convert dec_imm " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 48/76] target/microblaze: Fix cpu unwind for fpu exceptions Richard Henderson
` (31 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 48/76] target/microblaze: Fix cpu unwind for fpu exceptions
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (46 preceding siblings ...)
2020-08-31 16:05 ` [PULL 47/76] target/microblaze: Convert dec_fpu " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG Richard Henderson
` (30 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Restore the correct PC when an exception must be raised.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (47 preceding siblings ...)
2020-08-31 16:05 ` [PULL 48/76] target/microblaze: Fix cpu unwind for fpu exceptions Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
` (29 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (48 preceding siblings ...)
2020-08-31 16:05 ` [PULL 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 51/76] target/microblaze: Cache mem_index in DisasContext Richard Henderson
` (28 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 51/76] target/microblaze: Cache mem_index in DisasContext
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (49 preceding siblings ...)
2020-08-31 16:05 ` [PULL 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 52/76] target/microblaze: Fix cpu unwind for stackprot Richard Henderson
` (27 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Ideally, nothing outside the top-level of translation even
has access to env. Cache the value in init_disas_context.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 52/76] target/microblaze: Fix cpu unwind for stackprot
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (50 preceding siblings ...)
2020-08-31 16:05 ` [PULL 51/76] target/microblaze: Cache mem_index in DisasContext Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 53/76] target/microblaze: Convert dec_load and dec_store to decodetree Richard Henderson
` (26 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Restore the correct PC when an exception must be raised.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 53/76] target/microblaze: Convert dec_load and dec_store to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (51 preceding siblings ...)
2020-08-31 16:05 ` [PULL 52/76] target/microblaze: Fix cpu unwind for stackprot Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 54/76] target/microblaze: Assert no overlap in flags making up tb_flags Richard Henderson
` (25 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 54/76] target/microblaze: Assert no overlap in flags making up tb_flags
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (52 preceding siblings ...)
2020-08-31 16:05 ` [PULL 53/76] target/microblaze: Convert dec_load and dec_store to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 55/76] target/microblaze: Move bimm to BIMM_FLAG Richard Henderson
` (24 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Create MSR_TB_MASK. Use it in cpu_get_tb_cpu_state, and check
that IFLAGS_TB_MASK does not overlap.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 55/76] target/microblaze: Move bimm to BIMM_FLAG
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (53 preceding siblings ...)
2020-08-31 16:05 ` [PULL 54/76] target/microblaze: Assert no overlap in flags making up tb_flags Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed Richard Henderson
` (23 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (54 preceding siblings ...)
2020-08-31 16:05 ` [PULL 55/76] target/microblaze: Move bimm to BIMM_FLAG Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 57/76] target/microblaze: Store "current" iflags in insn_start Richard Henderson
` (22 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell, Edgar E . Iglesias
Do not call cpu_restore_state when no exception will be
delivered. This can lead to inconsistent cpu state.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 57/76] target/microblaze: Store "current" iflags in insn_start
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (55 preceding siblings ...)
2020-08-31 16:05 ` [PULL 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 58/76] tcg: Add tcg_get_insn_start_param Richard Henderson
` (21 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 58/76] tcg: Add tcg_get_insn_start_param
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (56 preceding siblings ...)
2020-08-31 16:05 ` [PULL 57/76] target/microblaze: Store "current" iflags in insn_start Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 59/76] target/microblaze: Use cc->do_unaligned_access Richard Henderson
` (20 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
MicroBlaze will shortly need to update a parameter in place.
Add an interface to read to match that for write.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 59/76] target/microblaze: Use cc->do_unaligned_access
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (57 preceding siblings ...)
2020-08-31 16:05 ` [PULL 58/76] tcg: Add tcg_get_insn_start_param Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set Richard Henderson
` (19 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (58 preceding siblings ...)
2020-08-31 16:05 ` [PULL 59/76] target/microblaze: Use cc->do_unaligned_access Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 61/76] target/microblaze: Replace delayed_branch " Richard Henderson
` (18 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
This more general update variable will be able to handle
delay slots as well.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 61/76] target/microblaze: Replace delayed_branch with tb_flags_to_set
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (59 preceding siblings ...)
2020-08-31 16:05 ` [PULL 60/76] target/microblaze: Replace clear_imm with tb_flags_to_set Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 62/76] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
` (17 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 62/76] target/microblaze: Tidy mb_cpu_dump_state
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (60 preceding siblings ...)
2020-08-31 16:05 ` [PULL 61/76] target/microblaze: Replace delayed_branch " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 63/76] target/microblaze: Convert brk and brki to decodetree Richard Henderson
` (16 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 63/76] target/microblaze: Convert brk and brki to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (61 preceding siblings ...)
2020-08-31 16:05 ` [PULL 62/76] target/microblaze: Tidy mb_cpu_dump_state Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 64/76] target/microblaze: Convert mbar " Richard Henderson
` (15 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 64/76] target/microblaze: Convert mbar to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (62 preceding siblings ...)
2020-08-31 16:05 ` [PULL 63/76] target/microblaze: Convert brk and brki to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 65/76] target/microblaze: Reorganize branching Richard Henderson
` (14 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Split this out of the normal branch instructions,
as it requires special handling.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 65/76] target/microblaze: Reorganize branching
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (63 preceding siblings ...)
2020-08-31 16:05 ` [PULL 64/76] target/microblaze: Convert mbar " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 66/76] target/microblaze: Convert dec_br to decodetree Richard Henderson
` (13 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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), tcg will remove the computation
into btarget, leaving us with just the tcg direct branching at the end.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 66/76] target/microblaze: Convert dec_br to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (64 preceding siblings ...)
2020-08-31 16:05 ` [PULL 65/76] target/microblaze: Reorganize branching Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 67/76] target/microblaze: Convert dec_bcc " Richard Henderson
` (12 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 67/76] target/microblaze: Convert dec_bcc to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (65 preceding siblings ...)
2020-08-31 16:05 ` [PULL 66/76] target/microblaze: Convert dec_br to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 68/76] target/microblaze: Convert dec_rts " Richard Henderson
` (11 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 68/76] target/microblaze: Convert dec_rts to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (66 preceding siblings ...)
2020-08-31 16:05 ` [PULL 67/76] target/microblaze: Convert dec_bcc " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte Richard Henderson
` (10 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (67 preceding siblings ...)
2020-08-31 16:05 ` [PULL 68/76] target/microblaze: Convert dec_rts " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 70/76] target/microblaze: Convert msrclr, msrset to decodetree Richard Henderson
` (9 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Since cpu_msr is no longer a 64-bit quantity, we can simplify
the arithmetic in these functions.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 70/76] target/microblaze: Convert msrclr, msrset to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (68 preceding siblings ...)
2020-08-31 16:05 ` [PULL 69/76] target/microblaze: Tidy do_rti, do_rtb, do_rte Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 71/76] target/microblaze: Convert dec_msr " Richard Henderson
` (8 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Split this out of dec_msr.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 71/76] target/microblaze: Convert dec_msr to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (69 preceding siblings ...)
2020-08-31 16:05 ` [PULL 70/76] target/microblaze: Convert msrclr, msrset to decodetree Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 72/76] target/microblaze: Convert dec_stream " Richard Henderson
` (7 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 72/76] target/microblaze: Convert dec_stream to decodetree
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (70 preceding siblings ...)
2020-08-31 16:05 ` [PULL 71/76] target/microblaze: Convert dec_msr " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 73/76] target/microblaze: Remove last of old decoder Richard Henderson
` (6 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 73/76] target/microblaze: Remove last of old decoder
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (71 preceding siblings ...)
2020-08-31 16:05 ` [PULL 72/76] target/microblaze: Convert dec_stream " Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:05 ` [PULL 74/76] target/microblaze: Remove cpu_R[0] Richard Henderson
` (5 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
All instructions have been convered. Issue sigill if decodetree
does not match. Remove argument decode from DisasContext.
Remove microblaze-decode.h.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 74/76] target/microblaze: Remove cpu_R[0]
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (72 preceding siblings ...)
2020-08-31 16:05 ` [PULL 73/76] target/microblaze: Remove last of old decoder Richard Henderson
@ 2020-08-31 16:05 ` Richard Henderson
2020-08-31 16:06 ` [PULL 75/76] target/microblaze: Add flags markup to some helpers Richard Henderson
` (4 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 75/76] target/microblaze: Add flags markup to some helpers
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (73 preceding siblings ...)
2020-08-31 16:05 ` [PULL 74/76] target/microblaze: Remove cpu_R[0] Richard Henderson
@ 2020-08-31 16:06 ` Richard Henderson
2020-08-31 16:06 ` [PULL 76/76] target/microblaze: Reduce linux-user address space to 32-bit Richard Henderson
` (3 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
The mmu_read, mmu_write, get, and put helpers do not touch the
general registers, or any of the other variables managed by tcg.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* [PULL 76/76] target/microblaze: Reduce linux-user address space to 32-bit
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (74 preceding siblings ...)
2020-08-31 16:06 ` [PULL 75/76] target/microblaze: Add flags markup to some helpers Richard Henderson
@ 2020-08-31 16:06 ` Richard Henderson
2020-09-01 0:21 ` [PULL 00/76] target/microblaze improvements no-reply
` (2 subsequent siblings)
78 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2020-08-31 16:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Edgar E . Iglesias, peter.maydell
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.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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] 80+ messages in thread
* Re: [PULL 00/76] target/microblaze improvements
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (75 preceding siblings ...)
2020-08-31 16:06 ` [PULL 76/76] target/microblaze: Reduce linux-user address space to 32-bit Richard Henderson
@ 2020-09-01 0:21 ` no-reply
2020-09-01 0:32 ` no-reply
2020-09-01 12:17 ` Peter Maydell
78 siblings, 0 replies; 80+ messages in thread
From: no-reply @ 2020-09-01 0:21 UTC (permalink / raw)
To: richard.henderson; +Cc: peter.maydell, qemu-devel
Patchew URL: https://patchew.org/QEMU/20200831160601.833692-1-richard.henderson@linaro.org/
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20200831160601.833692-1-richard.henderson@linaro.org
Subject: [PULL 00/76] target/microblaze improvements
=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
4bc08c6..2f4c51c master -> master
- [tag update] patchew/20200826171005.4055015-1-ehabkost@redhat.com -> patchew/20200826171005.4055015-1-ehabkost@redhat.com
- [tag update] patchew/20200827113259.25064-1-peter.maydell@linaro.org -> patchew/20200827113259.25064-1-peter.maydell@linaro.org
- [tag update] patchew/20200827124335.30586-1-leif@nuviainc.com -> patchew/20200827124335.30586-1-leif@nuviainc.com
- [tag update] patchew/20200827173051.31050-1-sw@weilnetz.de -> patchew/20200827173051.31050-1-sw@weilnetz.de
- [tag update] patchew/20200827175520.32355-1-sw@weilnetz.de -> patchew/20200827175520.32355-1-sw@weilnetz.de
- [tag update] patchew/20200827210920.111611-1-sw@weilnetz.de -> patchew/20200827210920.111611-1-sw@weilnetz.de
- [tag update] patchew/20200828141929.77854-1-richard.henderson@linaro.org -> patchew/20200828141929.77854-1-richard.henderson@linaro.org
- [tag update] patchew/20200828180243.443016-1-richard.henderson@linaro.org -> patchew/20200828180243.443016-1-richard.henderson@linaro.org
* [new tag] patchew/20200831235146.36045-1-david@gibson.dropbear.id.au -> patchew/20200831235146.36045-1-david@gibson.dropbear.id.au
Switched to a new branch 'test'
0d7dedb target/microblaze: Reduce linux-user address space to 32-bit
5f8c3e2 target/microblaze: Add flags markup to some helpers
466a318 target/microblaze: Remove cpu_R[0]
b1fb8b5 target/microblaze: Remove last of old decoder
0dfefb5 target/microblaze: Convert dec_stream to decodetree
c8b363c target/microblaze: Convert dec_msr to decodetree
7694f94 target/microblaze: Convert msrclr, msrset to decodetree
7dd5ab7 target/microblaze: Tidy do_rti, do_rtb, do_rte
539026b target/microblaze: Convert dec_rts to decodetree
4a40a45 target/microblaze: Convert dec_bcc to decodetree
eac8dd6 target/microblaze: Convert dec_br to decodetree
224c085 target/microblaze: Reorganize branching
f419c16 target/microblaze: Convert mbar to decodetree
c8837be target/microblaze: Convert brk and brki to decodetree
3a87b51 target/microblaze: Tidy mb_cpu_dump_state
1424196 target/microblaze: Replace delayed_branch with tb_flags_to_set
0ae7328 target/microblaze: Replace clear_imm with tb_flags_to_set
0954fbf target/microblaze: Use cc->do_unaligned_access
3c786be tcg: Add tcg_get_insn_start_param
15f0392 target/microblaze: Store "current" iflags in insn_start
dd4c8f4 target/microblaze: Fix no-op mb_cpu_transaction_failed
dd0128a target/microblaze: Move bimm to BIMM_FLAG
640419e target/microblaze: Assert no overlap in flags making up tb_flags
c53dbea target/microblaze: Convert dec_load and dec_store to decodetree
c725fe0 target/microblaze: Fix cpu unwind for stackprot
dbd989d target/microblaze: Cache mem_index in DisasContext
d927735 target/microblaze: Replace MSR_EE_FLAG with MSR_EE
d284d29 target/microblaze: Mark fpu helpers TCG_CALL_NO_WG
7e91cb3 target/microblaze: Fix cpu unwind for fpu exceptions
0a82365 target/microblaze: Convert dec_fpu to decodetree
fdc326c target/microblaze: Convert dec_imm to decodetree
46ffb06 target/microblaze: Convert dec_barrel to decodetree
fc30359 target/microblaze: Convert dec_bit to decodetree
9e7444e target/microblaze: Unwind properly when raising divide-by-zero
38ac916 target/microblaze: Convert dec_div to decodetree
a05d432 target/microblaze: Convert dec_mul to decodetree
15fe607 target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree
6320c68 target/microblaze: Convert dec_pattern to decodetree
9551f17 target/microblaze: Implement cmp and cmpu inline
873ee28 target/microblaze: Convert dec_sub to decodetree
165699d target/microblaze: Convert dec_add to decodetree
ff24f67 target/microblaze: Add decodetree infrastructure
212839a target/microblaze: Ensure imm constant is always available
c6fc5d4 target/microblaze: Remove LOG_DIS
6b9d549 target/microblaze: Remove empty D macros
634c628 target/microblaze: Remove DISAS_GNU
f6e12e6 target/microblaze: Remove SIM_COMPAT
fd60a2a target/microblaze: Convert to translator_loop
137c956 target/microblaze: Convert to DisasContextBase
e9d715a target/microblaze: Check singlestep_enabled in gen_goto_tb
c2aa981 target/microblaze: Use DISAS_NORETURN
24e5371 target/microblaze: Split out MSR[C] to its own variable
089d389 target/microblaze: Tidy mb_tcg_init
35e3d1a target/microblaze: Rename env_* tcg variables to cpu_*
504bece target/microblaze: Remove helper_debug and env->debug
d8b5940 target/microblaze: Mark raise_exception as noreturn
7608d65 target/microblaze: Tidy raising of exceptions
8945896 target/microblaze: Remove cpu_ear
b74816d target/microblaze: Fix width of EDR
9be24ee target/microblaze: Fix width of BTR
3f9dfbc target/microblaze: Fix width of FSR
cb55e5f target/microblaze: Fix width of ESR
8859a93 target/microblaze: Fix width of MSR
e7de39d target/microblaze: Fix width of PC and BTARGET
4b26167 target/microblaze: Split the cpu_SR array
1455001 target/microblaze: Split out EDR from env->sregs
67e6dce target/microblaze: Split out BTR from env->sregs
256029a target/microblaze: Split out FSR from env->sregs
7989da1 target/microblaze: Split out ESR from env->sregs
bb70861 target/microblaze: Split out EAR from env->sregs
dd5b138 target/microblaze: Split out MSR from env->sregs
97999ea target/microblaze: Split out PC from env->sregs
7de26dc target/microblaze: Tidy gdbstub
32104b84 tests/tcg: Do not require FE_* exception bits
2381e76 tests/tcg: Do not require FE_TOWARDZERO
32ade00 tests/tcg: Add microblaze to arches filter
=== OUTPUT BEGIN ===
1/76 Checking commit 32ade0099e18 (tests/tcg: Add microblaze to arches filter)
ERROR: line over 90 characters
#24: FILE: tests/tcg/configure.sh:97:
+ alpha|cris|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64)
total: 1 errors, 0 warnings, 8 lines checked
Patch 1/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/76 Checking commit 2381e76ba247 (tests/tcg: Do not require FE_TOWARDZERO)
3/76 Checking commit 32104b84fc2f (tests/tcg: Do not require FE_* exception bits)
4/76 Checking commit 7de26dc06890 (target/microblaze: Tidy gdbstub)
5/76 Checking commit 97999eaea67f (target/microblaze: Split out PC from env->sregs)
6/76 Checking commit dd5b138c2b12 (target/microblaze: Split out MSR from env->sregs)
7/76 Checking commit bb70861493b2 (target/microblaze: Split out EAR from env->sregs)
8/76 Checking commit 7989da1fafe5 (target/microblaze: Split out ESR from env->sregs)
9/76 Checking commit 256029a96446 (target/microblaze: Split out FSR from env->sregs)
10/76 Checking commit 67e6dce9f408 (target/microblaze: Split out BTR from env->sregs)
11/76 Checking commit 14550010ea94 (target/microblaze: Split out EDR from env->sregs)
12/76 Checking commit 4b26167a7837 (target/microblaze: Split the cpu_SR array)
ERROR: switch and case should be at the same indent
#125: FILE: target/microblaze/translate.c:543:
switch (sr) {
+ case SR_PC:
[...]
+ case SR_MSR:
[...]
+ case SR_BTR:
[...]
+ case SR_EDR:
ERROR: switch and case should be at the same indent
#154: FILE: target/microblaze/translate.c:579:
switch (sr) {
+ case SR_PC:
[...]
+ case SR_MSR:
total: 2 errors, 0 warnings, 287 lines checked
Patch 12/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
13/76 Checking commit e7de39d8569d (target/microblaze: Fix width of PC and BTARGET)
14/76 Checking commit 8859a934c315 (target/microblaze: Fix width of MSR)
15/76 Checking commit cb55e5fd1522 (target/microblaze: Fix width of ESR)
16/76 Checking commit 3f9dfbc2d82b (target/microblaze: Fix width of FSR)
17/76 Checking commit 9be24eea7275 (target/microblaze: Fix width of BTR)
18/76 Checking commit b74816d8c2ba (target/microblaze: Fix width of EDR)
19/76 Checking commit 89458966a79e (target/microblaze: Remove cpu_ear)
20/76 Checking commit 7608d65e99e3 (target/microblaze: Tidy raising of exceptions)
21/76 Checking commit d8b5940670c2 (target/microblaze: Mark raise_exception as noreturn)
22/76 Checking commit 504becee93e2 (target/microblaze: Remove helper_debug and env->debug)
23/76 Checking commit 35e3d1abbe73 (target/microblaze: Rename env_* tcg variables to cpu_*)
24/76 Checking commit 089d389698fa (target/microblaze: Tidy mb_tcg_init)
25/76 Checking commit 24e537176135 (target/microblaze: Split out MSR[C] to its own variable)
26/76 Checking commit c2aa981dc20c (target/microblaze: Use DISAS_NORETURN)
27/76 Checking commit e9d715a25322 (target/microblaze: Check singlestep_enabled in gen_goto_tb)
28/76 Checking commit 137c956c34e4 (target/microblaze: Convert to DisasContextBase)
29/76 Checking commit fd60a2a6cfe5 (target/microblaze: Convert to translator_loop)
30/76 Checking commit f6e12e6a6cd8 (target/microblaze: Remove SIM_COMPAT)
31/76 Checking commit 634c6287cd12 (target/microblaze: Remove DISAS_GNU)
32/76 Checking commit 6b9d54925c00 (target/microblaze: Remove empty D macros)
33/76 Checking commit c6fc5d4224a0 (target/microblaze: Remove LOG_DIS)
34/76 Checking commit 212839a3cd07 (target/microblaze: Ensure imm constant is always available)
35/76 Checking commit ff24f676c604 (target/microblaze: Add decodetree infrastructure)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16:
new file mode 100644
total: 0 errors, 1 warnings, 60 lines checked
Patch 35/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
36/76 Checking commit 165699da76c5 (target/microblaze: Convert dec_add to decodetree)
ERROR: spaces required around that '*' (ctx:WxV)
#256: FILE: target/microblaze/translate.c:330:
+static bool trans_zero(DisasContext *dc, arg_zero *arg)
^
total: 1 errors, 0 warnings, 279 lines checked
Patch 36/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
37/76 Checking commit 873ee2858743 (target/microblaze: Convert dec_sub to decodetree)
38/76 Checking commit 9551f1759c3a (target/microblaze: Implement cmp and cmpu inline)
39/76 Checking commit 6320c68f6ccb (target/microblaze: Convert dec_pattern to decodetree)
40/76 Checking commit 15fe607e07f7 (target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree)
41/76 Checking commit a05d43282444 (target/microblaze: Convert dec_mul to decodetree)
42/76 Checking commit 38ac91626de4 (target/microblaze: Convert dec_div to decodetree)
43/76 Checking commit 9e7444e60cb7 (target/microblaze: Unwind properly when raising divide-by-zero)
44/76 Checking commit fc30359d501b (target/microblaze: Convert dec_bit to decodetree)
ERROR: spaces required around that '*' (ctx:WxV)
#160: FILE: target/microblaze/translate.c:545:
+static bool trans_wdic(DisasContext *dc, arg_wdic *a)
^
total: 1 errors, 0 warnings, 227 lines checked
Patch 44/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
45/76 Checking commit 46ffb06bbf4c (target/microblaze: Convert dec_barrel to decodetree)
46/76 Checking commit fdc326c0c8ae (target/microblaze: Convert dec_imm to decodetree)
ERROR: spaces required around that '*' (ctx:WxV)
#33: FILE: target/microblaze/translate.c:480:
+static bool trans_imm(DisasContext *dc, arg_imm *arg)
^
total: 1 errors, 0 warnings, 44 lines checked
Patch 46/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
47/76 Checking commit 0a823659b840 (target/microblaze: Convert dec_fpu to decodetree)
48/76 Checking commit 7e91cb362270 (target/microblaze: Fix cpu unwind for fpu exceptions)
49/76 Checking commit d284d293a1f6 (target/microblaze: Mark fpu helpers TCG_CALL_NO_WG)
50/76 Checking commit d9277357cbd6 (target/microblaze: Replace MSR_EE_FLAG with MSR_EE)
51/76 Checking commit dbd989dfe4e1 (target/microblaze: Cache mem_index in DisasContext)
52/76 Checking commit c725fe02b326 (target/microblaze: Fix cpu unwind for stackprot)
53/76 Checking commit c53dbeaa6e85 (target/microblaze: Convert dec_load and dec_store to decodetree)
WARNING: Block comments use a leading /* on a separate line
#350: FILE: target/microblaze/translate.c:944:
+ /* FIXME: if the alignment is wrong, we should restore the value
total: 0 errors, 1 warnings, 791 lines checked
Patch 53/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
54/76 Checking commit 640419e5c31b (target/microblaze: Assert no overlap in flags making up tb_flags)
55/76 Checking commit dd0128a2fa65 (target/microblaze: Move bimm to BIMM_FLAG)
56/76 Checking commit dd4c8f4b01f8 (target/microblaze: Fix no-op mb_cpu_transaction_failed)
57/76 Checking commit 15f0392b1027 (target/microblaze: Store "current" iflags in insn_start)
58/76 Checking commit 3c786be3d027 (tcg: Add tcg_get_insn_start_param)
59/76 Checking commit 0954fbfc7898 (target/microblaze: Use cc->do_unaligned_access)
ERROR: spaces required around that '<<' (ctx:VxV)
#37: FILE: target/microblaze/cpu.h:82:
+#define ESR_W (1<<11) /* Unaligned word access */
^
total: 1 errors, 0 warnings, 204 lines checked
Patch 59/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
60/76 Checking commit 0ae7328b9266 (target/microblaze: Replace clear_imm with tb_flags_to_set)
61/76 Checking commit 1424196cc193 (target/microblaze: Replace delayed_branch with tb_flags_to_set)
62/76 Checking commit 3a87b5189820 (target/microblaze: Tidy mb_cpu_dump_state)
63/76 Checking commit c8837be1e305 (target/microblaze: Convert brk and brki to decodetree)
64/76 Checking commit f419c16adfcc (target/microblaze: Convert mbar to decodetree)
ERROR: spaces required around that '+' (ctx:ExV)
#59: FILE: target/microblaze/translate.c:1153:
+ +offsetof(CPUState, halted));
^
total: 1 errors, 0 warnings, 111 lines checked
Patch 64/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
65/76 Checking commit 224c085312a4 (target/microblaze: Reorganize branching)
66/76 Checking commit eac8dd68662b (target/microblaze: Convert dec_br to decodetree)
67/76 Checking commit 4a40a45501d7 (target/microblaze: Convert dec_bcc to decodetree)
ERROR: spaces required around that '*' (ctx:WxV)
#125: FILE: target/microblaze/translate.c:1134:
+ static bool trans_##NAME(DisasContext *dc, arg_typea_bc *arg) \
^
ERROR: spaces required around that '*' (ctx:WxV)
#127: FILE: target/microblaze/translate.c:1136:
+ static bool trans_##NAME##d(DisasContext *dc, arg_typea_bc *arg) \
^
ERROR: spaces required around that '*' (ctx:WxV)
#129: FILE: target/microblaze/translate.c:1138:
+ static bool trans_##NAME##i(DisasContext *dc, arg_typeb_bc *arg) \
^
ERROR: spaces required around that '*' (ctx:WxV)
#131: FILE: target/microblaze/translate.c:1140:
+ static bool trans_##NAME##id(DisasContext *dc, arg_typeb_bc *arg) \
^
total: 4 errors, 0 warnings, 179 lines checked
Patch 67/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
68/76 Checking commit 539026b12c05 (target/microblaze: Convert dec_rts to decodetree)
69/76 Checking commit 7dd5ab73d21a (target/microblaze: Tidy do_rti, do_rtb, do_rte)
70/76 Checking commit 7694f94e3e85 (target/microblaze: Convert msrclr, msrset to decodetree)
71/76 Checking commit c8b363c50946 (target/microblaze: Convert dec_msr to decodetree)
72/76 Checking commit 0dfefb59890f (target/microblaze: Convert dec_stream to decodetree)
73/76 Checking commit b1fb8b5e7ace (target/microblaze: Remove last of old decoder)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#17:
deleted file mode 100644
total: 0 errors, 1 warnings, 128 lines checked
Patch 73/76 has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
74/76 Checking commit 466a31810f81 (target/microblaze: Remove cpu_R[0])
75/76 Checking commit 5f8c3e2d6c17 (target/microblaze: Add flags markup to some helpers)
76/76 Checking commit 0d7dedb8e895 (target/microblaze: Reduce linux-user address space to 32-bit)
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at
http://patchew.org/logs/20200831160601.833692-1-richard.henderson@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PULL 00/76] target/microblaze improvements
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (76 preceding siblings ...)
2020-09-01 0:21 ` [PULL 00/76] target/microblaze improvements no-reply
@ 2020-09-01 0:32 ` no-reply
2020-09-01 12:17 ` Peter Maydell
78 siblings, 0 replies; 80+ messages in thread
From: no-reply @ 2020-09-01 0:32 UTC (permalink / raw)
To: richard.henderson; +Cc: peter.maydell, qemu-devel
Patchew URL: https://patchew.org/QEMU/20200831160601.833692-1-richard.henderson@linaro.org/
Hi,
This series failed the docker-mingw@fedora build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===
Host machine cpu: x86_64
Target machine cpu family: x86
Target machine cpu: x86_64
../src/meson.build:10: WARNING: Module unstable-keyval has no backwards or forwards compatibility and might not exist in future releases.
Program sh found: YES
Program python3 found: YES (/usr/bin/python3)
C++ compiler for the host machine: x86_64-w64-mingw32-g++ (gcc 9.2.1 "x86_64-w64-mingw32-g++ (GCC) 9.2.1 20190827 (Fedora MinGW 9.2.1-6.fc32)")
---
Linux keyring: NO
Found ninjatool-1.8 at /tmp/qemu-test/build/ninjatool
WARNING: custom_target 'shared QAPI source files' has more than one output! Using the first one.
WARNING: custom_target 'QGA QAPI files' has more than one output! Using the first one.
WARNING: custom_target 'QAPI files for qemu-storage-daemon' has more than one output! Using the first one.
WARNING: custom_target 'QAPI doc' has more than one output! Using the first one.
WARNING: custom_target 'tools man pages' has more than one output! Using the first one.
WARNING: custom_target 'system man pages' has more than one output! Using the first one.
Command line for building ['libcommon.fa'] is long, using a response file
/usr/bin/python3 -B /tmp/qemu-test/src/meson/meson.py introspect --tests | /usr/bin/python3 -B scripts/mtest2make.py > Makefile.mtest
./ninjatool -t ninja2make --omit clean dist uninstall < build.ninja > Makefile.ninja
---
Host machine cpu: i386
Target machine cpu family: x86
Target machine cpu: i386
../src/meson.build:10: WARNING: Module unstable-keyval has no backwards or forwards compatibility and might not exist in future releases.
Program sh found: YES
Program python3 found: YES (/usr/bin/python3)
C++ compiler for the host machine: i686-w64-mingw32-g++ (gcc 9.2.1 "i686-w64-mingw32-g++ (GCC) 9.2.1 20190827 (Fedora MinGW 9.2.1-6.fc32)")
---
Linux keyring: NO
Found ninjatool-1.8 at /tmp/qemu-test/build/ninjatool
WARNING: custom_target 'shared QAPI source files' has more than one output! Using the first one.
WARNING: custom_target 'QGA QAPI files' has more than one output! Using the first one.
WARNING: custom_target 'QAPI files for qemu-storage-daemon' has more than one output! Using the first one.
WARNING: custom_target 'QAPI doc' has more than one output! Using the first one.
WARNING: custom_target 'tools man pages' has more than one output! Using the first one.
WARNING: custom_target 'system man pages' has more than one output! Using the first one.
Command line for building ['libcommon.fa'] is long, using a response file
/usr/bin/python3 -B /tmp/qemu-test/src/meson/meson.py introspect --tests | /usr/bin/python3 -B scripts/mtest2make.py > Makefile.mtest
./ninjatool -t ninja2make --omit clean dist uninstall < build.ninja > Makefile.ninja
---
from /tmp/qemu-test/src/include/exec/exec-all.h:26,
from ../src/target/i386/machine.c:3:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1533: libqemu-x86_64-softmmu.fa.p/target_i386_machine.c.obj] Error 1
make: *** Waiting for unfinished jobs....
In file included from ../src/hw/i386/kvmvapic.c:24:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1546: libqemu-x86_64-softmmu.fa.p/hw_i386_kvmvapic.c.obj] Error 1
In file included from /tmp/qemu-test/src/include/exec/cpu_ldst.h:295,
from ../src/target/i386/mpx_helper.c:23:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1554: libqemu-x86_64-softmmu.fa.p/target_i386_mpx_helper.c.obj] Error 1
In file included from /tmp/qemu-test/src/include/exec/cpu_ldst.h:295,
from /tmp/qemu-test/src/include/exec/exec-all.h:26,
from ../src/target/i386/bpt_helper.c:22:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1559: libqemu-x86_64-softmmu.fa.p/target_i386_bpt_helper.c.obj] Error 1
In file included from /tmp/qemu-test/src/include/exec/cpu_ldst.h:295,
from /tmp/qemu-test/src/include/exec/exec-all.h:26,
from ../src/target/i386/misc_helper.c:24:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1553: libqemu-x86_64-softmmu.fa.p/target_i386_misc_helper.c.obj] Error 1
In file included from /tmp/qemu-test/src/include/exec/cpu_ldst.h:295,
from /tmp/qemu-test/src/include/exec/exec-all.h:26,
from ../src/target/i386/cpu.c:27:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1556: libqemu-x86_64-softmmu.fa.p/target_i386_cpu.c.obj] Error 1
In file included from /tmp/qemu-test/src/include/exec/cpu_ldst.h:295,
from /tmp/qemu-test/src/include/exec/exec-all.h:26,
from ../src/target/i386/seg_helper.c:25:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1557: libqemu-x86_64-softmmu.fa.p/target_i386_seg_helper.c.obj] Error 1
In file included from /tmp/qemu-test/src/include/exec/cpu_ldst.h:295,
from /tmp/qemu-test/src/include/exec/exec-all.h:26,
from ../src/target/i386/translate.c:24:
/tmp/qemu-test/src/include/tcg/tcg.h: In function 'tcg_get_insn_start_param':
/tmp/qemu-test/src/include/tcg/tcg.h:796:49: error: left shift count >= width of type [-Werror=shift-count-overflow]
796 | (tcg_get_insn_param(op, arg * 2 + 1) << 32);
| ^~
cc1: all warnings being treated as errors
make: *** [Makefile.ninja:1560: libqemu-x86_64-softmmu.fa.p/target_i386_translate.c.obj] Error 1
Traceback (most recent call last):
File "./tests/docker/docker.py", line 709, in <module>
sys.exit(main())
---
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=08be3efbe88a4e8ba88243d02c759bbc', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-h13z94vm/src/docker-src.2020-08-31-20.22.26.29191:/var/tmp/qemu:z,ro', 'qemu/fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit status 2.
filter=--filter=label=com.qemu.instance.uuid=08be3efbe88a4e8ba88243d02c759bbc
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-h13z94vm/src'
make: *** [docker-run-test-mingw@fedora] Error 2
real 9m57.739s
user 0m22.204s
The full log is available at
http://patchew.org/logs/20200831160601.833692-1-richard.henderson@linaro.org/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PULL 00/76] target/microblaze improvements
2020-08-31 16:04 [PULL 00/76] target/microblaze improvements Richard Henderson
` (77 preceding siblings ...)
2020-09-01 0:32 ` no-reply
@ 2020-09-01 12:17 ` Peter Maydell
78 siblings, 0 replies; 80+ messages in thread
From: Peter Maydell @ 2020-09-01 12:17 UTC (permalink / raw)
To: Richard Henderson; +Cc: QEMU Developers
On Mon, 31 Aug 2020 at 17:06, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> At Edgar's request, generating the pull-request for this.
>
> r~
>
>
>
> The following changes since commit 39335fab59e11cfda9b7cf63929825db2dd3a3e0:
>
> Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.2-pull-request' into staging (2020-08-28 22:30:11 +0100)
>
> are available in the Git repository at:
>
> https://github.com/rth7680/qemu.git tags/pull-mb-20200831
>
> for you to fetch changes up to 7233c0d0b0f5b65fcf6d6423de069ddf9f916392:
>
> target/microblaze: Reduce linux-user address space to 32-bit (2020-08-31 08:45:45 -0700)
>
> ----------------------------------------------------------------
> Convert microblaze to generic translator loop
> Convert microblaze to decodetree
> Fix mb_cpu_transaction_failed
> Other misc cleanups
The patchew complaints about shifts greater than the width of the
type look legit -- could you fix them and resend, please?
thanks
-- PMM
^ permalink raw reply [flat|nested] 80+ messages in thread