diff options
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index 65f2caff3e..592e4e3cd0 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -5486,8 +5486,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) } break; case 26: - tcg_gen_movi_tl(arg, 0); /* unimplemented */ - rn = "ECC"; + switch (sel) { + case 0: + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); + rn = "ErrCtl"; + break; + default: + goto cp0_unimplemented; + } break; case 27: switch (sel) { @@ -6136,8 +6142,15 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) } break; case 26: - /* ignored */ - rn = "ECC"; + switch (sel) { + case 0: + gen_helper_mtc0_errctl(cpu_env, arg); + ctx->bstate = BS_STOP; + rn = "ErrCtl"; + break; + default: + goto cp0_unimplemented; + } break; case 27: switch (sel) { @@ -6762,8 +6775,14 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) } break; case 26: - tcg_gen_movi_tl(arg, 0); /* unimplemented */ - rn = "ECC"; + switch (sel) { + case 0: + gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl)); + rn = "ErrCtl"; + break; + default: + goto cp0_unimplemented; + } break; case 27: switch (sel) { @@ -7404,8 +7423,15 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) } break; case 26: - /* ignored */ - rn = "ECC"; + switch (sel) { + case 0: + gen_helper_mtc0_errctl(cpu_env, arg); + ctx->bstate = BS_STOP; + rn = "ErrCtl"; + break; + default: + goto cp0_unimplemented; + } break; case 27: switch (sel) { @@ -11190,6 +11216,15 @@ static void gen_addiupc (DisasContext *ctx, int rx, int imm, tcg_temp_free(t0); } +static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base, + int16_t offset) +{ + TCGv_i32 t0 = tcg_const_i32(op); + TCGv t1 = tcg_temp_new(); + gen_base_offset_addr(ctx, t1, base, offset); + gen_helper_cache(cpu_env, t1, t0); +} + #if defined(TARGET_MIPS64) static void decode_i64_mips16 (DisasContext *ctx, int ry, int funct, int16_t offset, @@ -13741,7 +13776,9 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx) switch (minor) { case CACHE: check_cp0_enabled(ctx); - /* Treat as no-op. */ + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, imm); + } break; case LWC2: case SWC2: @@ -17195,7 +17232,9 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) break; case R6_OPC_CACHE: check_cp0_enabled(ctx); - /* Treat as NOP. */ + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, imm); + } break; case R6_OPC_SC: gen_st_cond(ctx, op1, rt, rs, imm); @@ -19304,6 +19343,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) check_insn_opc_removed(ctx, ISA_MIPS32R6); check_cp0_enabled(ctx); check_insn(ctx, ISA_MIPS3 | ISA_MIPS32); + if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { + gen_cache_operation(ctx, rt, rs, imm); + } /* Treat as NOP. */ break; case OPC_PREF: |