diff mbox series

[v9,50/84] target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS

Message ID 1534431497-1385-51-git-send-email-aleksandar.markovic@rt-rk.com
State New
Headers show
Series Add nanoMIPS support to QEMU | expand

Commit Message

Aleksandar Markovic Aug. 16, 2018, 2:57 p.m. UTC
From: Stefan Markovic <smarkovic@wavecomp.com>

Update BadInstr, BadInstrP,and BadInstrX registers for nanoMIPS.
The same support for pre-nanoMIPS remains unimplemented.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/helper.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Richard Henderson Aug. 16, 2018, 7:29 p.m. UTC | #1
On 08/16/2018 07:57 AM, Aleksandar Markovic wrote:
> +        if ((env->CP0_Config3 & (1 << CP0C3_BP)) &&
> +            (env->hflags & MIPS_HFLAG_BMASK)) {
> +            if (!(env->hflags & MIPS_HFLAG_B16)) {
> +                env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4);
> +            } else {
> +                env->CP0_BadInstrP =
> +                    (cpu_lduw_code(env, env->active_tc.PC - 2)) << 16;
> +            }

Does BadInstrP really make sense for nanomips?  I do still see it in the
documentation, but I thought that was all about the branch delay slot, which is
no longer present.

Patch 39 began avoiding the set of BMASK.  So you can no longer rely on it
here.  Do we need a different mechanism to support BadInstrP, or do we really
need to keep BMASK?


r~
diff mbox series

Patch

diff --git a/target/mips/helper.c b/target/mips/helper.c
index e215af9..b25e000 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -682,6 +682,31 @@  static void set_hflags_for_handler (CPUMIPSState *env)
 
 static inline void set_badinstr_registers(CPUMIPSState *env)
 {
+    if (env->insn_flags & ISA_NANOMIPS32) {
+        if (env->CP0_Config3 & (1 << CP0C3_BI)) {
+            uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16;
+            if ((instr & 0x10000000) == 0) {
+                instr |= cpu_lduw_code(env, env->active_tc.PC + 2);
+            }
+            env->CP0_BadInstr = instr;
+
+            if ((instr & 0xFC000000) == 0x60000000) {
+                instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16;
+                env->CP0_BadInstrX = instr;
+            }
+        }
+        if ((env->CP0_Config3 & (1 << CP0C3_BP)) &&
+            (env->hflags & MIPS_HFLAG_BMASK)) {
+            if (!(env->hflags & MIPS_HFLAG_B16)) {
+                env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4);
+            } else {
+                env->CP0_BadInstrP =
+                    (cpu_lduw_code(env, env->active_tc.PC - 2)) << 16;
+            }
+        }
+        return;
+    }
+
     if (env->hflags & MIPS_HFLAG_M16) {
         /* TODO: add BadInstr support for microMIPS */
         return;