summaryrefslogtreecommitdiffstats
path: root/target-mips/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 76deb7b..2b3befb 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1072,6 +1072,7 @@ typedef struct DisasContext {
uint32_t hflags, saved_hflags;
int bstate;
target_ulong btarget;
+ bool ulri;
} DisasContext;
enum {
@@ -4215,7 +4216,18 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
rn = "ContextConfig";
+ goto die;
// break;
+ case 2:
+ if (ctx->ulri) {
+ tcg_gen_ld32s_tl(arg, cpu_env,
+ offsetof(CPUMIPSState,
+ active_tc.CP0_UserLocal));
+ rn = "UserLocal";
+ } else {
+ tcg_gen_movi_tl(arg, 0);
+ }
+ break;
default:
goto die;
}
@@ -4802,7 +4814,15 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
rn = "ContextConfig";
+ goto die;
// break;
+ case 2:
+ if (ctx->ulri) {
+ tcg_gen_st_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
+ }
+ break;
default:
goto die;
}
@@ -4862,6 +4882,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 0:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_hwrena(cpu_env, arg);
+ ctx->bstate = BS_STOP;
rn = "HWREna";
break;
default:
@@ -5406,7 +5427,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
rn = "ContextConfig";
+ goto die;
// break;
+ case 2:
+ if (ctx->ulri) {
+ tcg_gen_ld_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
+ } else {
+ tcg_gen_movi_tl(arg, 0);
+ }
+ break;
default:
goto die;
}
@@ -5978,7 +6009,15 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
rn = "ContextConfig";
+ goto die;
// break;
+ case 2:
+ if (ctx->ulri) {
+ tcg_gen_st_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
+ }
+ break;
default:
goto die;
}
@@ -6038,6 +6077,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 0:
check_insn(ctx, ISA_MIPS32R2);
gen_helper_mtc0_hwrena(cpu_env, arg);
+ ctx->bstate = BS_STOP;
rn = "HWREna";
break;
default:
@@ -9060,12 +9100,20 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
break;
case 29:
#if defined(CONFIG_USER_ONLY)
- tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
+ tcg_gen_ld_tl(t0, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
gen_store_gpr(t0, rt);
break;
#else
- /* XXX: Some CPUs implement this in hardware.
- Not supported yet. */
+ if ((ctx->hflags & MIPS_HFLAG_CP0) ||
+ (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
+ tcg_gen_ld_tl(t0, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ gen_store_gpr(t0, rt);
+ } else {
+ generate_exception(ctx, EXCP_RI);
+ }
+ break;
#endif
default: /* Invalid */
MIPS_INVAL("rdhwr");
@@ -15609,6 +15657,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
ctx.bstate = BS_NONE;
/* Restore delay slot state from the tb context. */
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
+ ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
restore_cpu_state(env, &ctx);
#ifdef CONFIG_USER_ONLY
ctx.mem_idx = MIPS_HFLAG_UM;
OpenPOWER on IntegriCloud