@@ -554,7 +554,7 @@ struct CPUMIPSState {
#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
uint32_t hflags; /* CPU State */
/* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK 0x1F5807FF
+#define MIPS_HFLAG_TMASK 0x3F5807FF
#define MIPS_HFLAG_MODE 0x00007 /* execution modes */
/* The KSU flags must be the lowest bits in hflags. The flag order
must be the same as defined for CP0 Status. This allows to use
@@ -605,6 +605,7 @@ struct CPUMIPSState {
#define MIPS_HFLAG_ELPA 0x4000000
#define MIPS_HFLAG_ITC_CACHE 0x8000000 /* CACHE instr. operates on ITC tag */
#define MIPS_HFLAG_ERL 0x10000000 /* error level flag */
+#define MIPS_HFLAG_XNP 0x20000000
target_ulong btarget; /* Jump / branch target */
target_ulong bcond; /* Branch condition (if needed) */
@@ -308,7 +308,7 @@ static inline void compute_hflags(CPUMIPSState *env)
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
- MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL);
+ MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL | MIPS_HFLAG_XNP);
if (env->CP0_Status & (1 << CP0St_ERL)) {
env->hflags |= MIPS_HFLAG_ERL;
}
@@ -402,6 +402,9 @@ static inline void compute_hflags(CPUMIPSState *env)
env->hflags |= MIPS_HFLAG_ELPA;
}
}
+ if (env->CP0_Config5 & (1 << CP0C5_XNP)) {
+ env->hflags |= MIPS_HFLAG_XNP;
+ }
}
void cpu_mips_tlb_flush(CPUMIPSState *env);
@@ -1902,6 +1902,18 @@ static inline void check_mvh(DisasContext *ctx)
}
#endif
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 XNP bit is set.
+ */
+static inline void check_xnp(DisasContext *ctx)
+{
+ if (unlikely(ctx->hflags & MIPS_HFLAG_XNP)) {
+ generate_exception_end(ctx, EXCP_RI);
+ }
+}
+
+
/* Define small wrappers for gen_load_fpr* so that we have a uniform
calling interface for 32 and 64-bit FPRs. No sense in changing
all callers for gen_load_fpr32 when we need the CTX parameter for