diff options
Diffstat (limited to 'target/mips/translate.c')
-rw-r--r-- | target/mips/translate.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/target/mips/translate.c b/target/mips/translate.c index d51330c2f0..d745bd2803 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -388,6 +388,7 @@ enum { OPC_BSHFL = 0x20 | OPC_SPECIAL3, OPC_DBSHFL = 0x24 | OPC_SPECIAL3, OPC_RDHWR = 0x3B | OPC_SPECIAL3, + OPC_GINV = 0x3D | OPC_SPECIAL3, /* Loongson 2E */ OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3, @@ -2548,6 +2549,7 @@ typedef struct DisasContext { bool abs2008; bool saar; bool mi; + int gi; } DisasContext; #define DISAS_STOP DISAS_TARGET_0 @@ -7131,6 +7133,11 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) tcg_gen_ext32s_tl(arg, arg); register_name = "UserLocal"; break; + case CP0_REG04__MMID: + CP0_CHECK(ctx->mi); + gen_helper_mtc0_memorymapid(cpu_env, arg); + register_name = "MMID"; + break; default: goto cp0_unimplemented; } @@ -7871,6 +7878,11 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); register_name = "UserLocal"; break; + case CP0_REG04__MMID: + CP0_CHECK(ctx->mi); + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); + register_name = "MMID"; + break; default: goto cp0_unimplemented; } @@ -8629,6 +8641,11 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); register_name = "UserLocal"; break; + case CP0_REG04__MMID: + CP0_CHECK(ctx->mi); + gen_helper_mtc0_memorymapid(cpu_env, arg); + register_name = "MMID"; + break; default: goto cp0_unimplemented; } @@ -9351,6 +9368,11 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) offsetof(CPUMIPSState, active_tc.CP0_UserLocal)); register_name = "UserLocal"; break; + case CP0_REG04__MMID: + CP0_CHECK(ctx->mi); + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID)); + register_name = "MMID"; + break; default: goto cp0_unimplemented; } @@ -27209,6 +27231,25 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) } } break; +#ifndef CONFIG_USER_ONLY + case OPC_GINV: + if (unlikely(ctx->gi <= 1)) { + generate_exception_end(ctx, EXCP_RI); + } + check_cp0_enabled(ctx); + switch ((ctx->opcode >> 6) & 3) { + case 0: /* GINVI */ + /* Treat as NOP. */ + break; + case 2: /* GINVT */ + gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2)); + break; + default: + generate_exception_end(ctx, EXCP_RI); + break; + } + break; +#endif #if defined(TARGET_MIPS64) case R6_OPC_SCD: gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false); @@ -30767,6 +30808,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1; ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1; + ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3; restore_cpu_state(env, ctx); #ifdef CONFIG_USER_ONLY ctx->mem_idx = MIPS_HFLAG_UM; @@ -31227,8 +31269,8 @@ void cpu_state_reset(CPUMIPSState *env) if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { env->CP0_CMGCRBase = 0x1fbf8000 >> 4; } - env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ? - 0x3ff : 0xff; + env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ? + 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); /* * Vectored interrupts not implemented, timer on int 7, |