diff --git a/qemu/target/mips/cpu.h b/qemu/target/mips/cpu.h index ac8354ba..f304c36b 100644 --- a/qemu/target/mips/cpu.h +++ b/qemu/target/mips/cpu.h @@ -795,6 +795,7 @@ struct CPUMIPSState { /* MIPS DSP resources access. */ #define MIPS_HFLAG_DSP 0x080000 /* Enable access to MIPS DSP resources. */ #define MIPS_HFLAG_DSPR2 0x100000 /* Enable access to MIPS DSPR2 resources. */ +#define MIPS_HFLAG_DSPR3 0x20000000 /* Enable access to MIPS DSPR3 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 */ diff --git a/qemu/target/mips/internal.h b/qemu/target/mips/internal.h index f9b3f402..49af03bf 100644 --- a/qemu/target/mips/internal.h +++ b/qemu/target/mips/internal.h @@ -311,8 +311,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_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE | - MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL); + MIPS_HFLAG_DSPR3 | MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | + MIPS_HFLAG_FRE | MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL); if (env->CP0_Status & (1 << CP0St_ERL)) { env->hflags |= MIPS_HFLAG_ERL; } @@ -359,7 +359,12 @@ static inline void compute_hflags(CPUMIPSState *env) (env->CP0_Config5 & (1 << CP0C5_SBRI))) { env->hflags |= MIPS_HFLAG_SBRI; } - if (env->insn_flags & ASE_DSPR2) { + if (env->insn_flags & ASE_DSPR3) { + if (env->CP0_Status & (1 << CP0St_MX)) { + env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 | + MIPS_HFLAG_DSPR3; + } + } else if (env->insn_flags & ASE_DSPR2) { /* Enables access MIPS DSP resources, now our cpu is DSP ASER2, so enable to access DSPR2 resources. */ if (env->CP0_Status & (1 << CP0St_MX)) { diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 8b195a79..c9e1e3cc 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -2415,6 +2415,17 @@ static inline void check_dspr2(DisasContext *ctx) } } +static inline void check_dspr3(DisasContext *ctx) +{ + if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR3))) { + if (ctx->insn_flags & ASE_DSP) { + generate_exception_end(ctx, EXCP_DSPDIS); + } else { + generate_exception_end(ctx, EXCP_RI); + } + } +} + /* This code generates a "reserved instruction" exception if the CPU does not support the instruction set corresponding to flags. */ static inline void check_insn(DisasContext *ctx, uint64_t flags) @@ -20778,7 +20789,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s); break; case NM_BPOSGE32C: - check_dspr2(ctx); + check_dspr3(ctx); { int32_t imm = extract32(ctx->opcode, 1, 13) | extract32(ctx->opcode, 0, 1) << 13; diff --git a/qemu/target/mips/translate_init.c b/qemu/target/mips/translate_init.c index fac87e27..02225dae 100644 --- a/qemu/target/mips/translate_init.c +++ b/qemu/target/mips/translate_init.c @@ -409,7 +409,7 @@ const mips_def_t mips_defs[] = (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13), 0,0, 0, - CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT, + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT, MMU_TYPE_R4000, }, { @@ -659,7 +659,7 @@ const mips_def_t mips_defs[] = 0, (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | (1U << CP0PG_RIE), 0, - CPU_NANOMIPS32 | ASE_DSP | ASE_DSPR2 | ASE_MT, + CPU_NANOMIPS32 | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_MT, MMU_TYPE_R4000, }, #if defined(TARGET_MIPS64)