diff options
-rw-r--r-- | target-mips/cpu.h | 11 | ||||
-rw-r--r-- | target-mips/translate.c | 24 |
2 files changed, 32 insertions, 3 deletions
diff --git a/target-mips/cpu.h b/target-mips/cpu.h index c66a725..ce9a7a2 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -410,6 +410,7 @@ struct CPUMIPSState { #define CP0C5_CV 29 #define CP0C5_EVA 28 #define CP0C5_MSAEn 27 +#define CP0C5_SBRI 6 #define CP0C5_UFR 2 #define CP0C5_NFExists 0 int32_t CP0_Config6; @@ -461,7 +462,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 0x1807FF +#define MIPS_HFLAG_TMASK 0x5807FF #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 @@ -505,6 +506,7 @@ struct CPUMIPSState { #define MIPS_HFLAG_DSPR2 0x100000 /* Enable access to MIPS DSPR2 resources. */ /* Extra flag about HWREna register. */ #define MIPS_HFLAG_HWRENA_ULR 0x200000 /* ULR bit from HWREna is set. */ +#define MIPS_HFLAG_SBRI 0x400000 /* R6 SDBBP causes RI excpt. in user mode */ target_ulong btarget; /* Jump / branch target */ target_ulong bcond; /* Branch condition (if needed) */ @@ -760,7 +762,8 @@ static inline void compute_hflags(CPUMIPSState *env) { env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | - MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2); + MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 | + MIPS_HFLAG_SBRI); if (!(env->CP0_Status & (1 << CP0St_EXL)) && !(env->CP0_Status & (1 << CP0St_ERL)) && !(env->hflags & MIPS_HFLAG_DM)) { @@ -796,6 +799,10 @@ static inline void compute_hflags(CPUMIPSState *env) if (env->CP0_Status & (1 << CP0St_FR)) { env->hflags |= MIPS_HFLAG_F64; } + if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_KM) && + (env->CP0_Config5 & (1 << CP0C5_SBRI))) { + env->hflags |= MIPS_HFLAG_SBRI; + } if (env->insn_flags & ASE_DSPR2) { /* Enables access MIPS DSP resources, now our cpu is DSP ASER2, so enable to access DSPR2 resources. */ diff --git a/target-mips/translate.c b/target-mips/translate.c index 3e6e990..c7a8bbc 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -6225,6 +6225,14 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3)); rn = "Config3"; break; + case 4: + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4)); + rn = "Config4"; + break; + case 5: + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); + rn = "Config5"; + break; /* 6,7 are implementation dependent */ case 6: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); @@ -6843,6 +6851,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) /* ignored */ rn = "Config3"; break; + case 4: + /* currently ignored */ + rn = "Config4"; + break; + case 5: + gen_helper_mtc0_config5(cpu_env, arg); + rn = "Config5"; + /* Stop translation as we may have switched the execution mode */ + ctx->bstate = BS_STOP; + break; /* 6,7 are implementation dependent */ default: rn = "Invalid config selector"; @@ -15801,7 +15819,11 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) } break; case R6_OPC_SDBBP: - generate_exception(ctx, EXCP_DBp); + if (ctx->hflags & MIPS_HFLAG_SBRI) { + generate_exception(ctx, EXCP_RI); + } else { + generate_exception(ctx, EXCP_DBp); + } break; #if defined(TARGET_MIPS64) case OPC_DLSA: |