aboutsummaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
authorLeon Alrae <leon.alrae@imgtec.com>2014-07-07 11:23:59 +0100
committerLeon Alrae <leon.alrae@imgtec.com>2014-11-03 11:48:34 +0000
commit7207c7f9d74816c32783a394d8072d1f978157ac (patch)
tree05c22755fc89eceee9d23533de96bc06d9abdd97 /target-mips/translate.c
parent2fb58b73746e2f99ac85e82160277b18b18279be (diff)
target-mips: update PageGrain and m{t,f}c0 EntryLo{0,1}
PageGrain needs rw bitmask which differs between MIPS architectures. In pre-R6 if RIXI is supported, PageGrain.XIE and PageGrain.RIE are writeable, whereas in R6 they are read-only 1. On MIPS64 mtc0 instruction left shifts bits 31:30 for MIPS32 backward compatiblity, therefore there are separate mtc0 and dmtc0 helpers. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 167f9bc545..e8933a9dd4 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1171,6 +1171,7 @@ typedef struct DisasContext {
target_ulong btarget;
bool ulri;
int kscrexist;
+ bool rxi;
} DisasContext;
enum {
@@ -4659,6 +4660,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
+#if defined(TARGET_MIPS64)
+ if (ctx->rxi) {
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_andi_tl(tmp, arg, (3ull << 62));
+ tcg_gen_shri_tl(tmp, tmp, 32);
+ tcg_gen_or_tl(arg, arg, tmp);
+ tcg_temp_free(tmp);
+ }
+#endif
tcg_gen_ext32s_tl(arg, arg);
rn = "EntryLo0";
break;
@@ -4705,6 +4715,15 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
switch (sel) {
case 0:
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
+#if defined(TARGET_MIPS64)
+ if (ctx->rxi) {
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_andi_tl(tmp, arg, (3ull << 62));
+ tcg_gen_shri_tl(tmp, tmp, 32);
+ tcg_gen_or_tl(arg, arg, tmp);
+ tcg_temp_free(tmp);
+ }
+#endif
tcg_gen_ext32s_tl(arg, arg);
rn = "EntryLo1";
break;
@@ -6480,7 +6499,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 2:
switch (sel) {
case 0:
- gen_helper_mtc0_entrylo0(cpu_env, arg);
+ gen_helper_dmtc0_entrylo0(cpu_env, arg);
rn = "EntryLo0";
break;
case 1:
@@ -6525,7 +6544,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 3:
switch (sel) {
case 0:
- gen_helper_mtc0_entrylo1(cpu_env, arg);
+ gen_helper_dmtc0_entrylo1(cpu_env, arg);
rn = "EntryLo1";
break;
default:
@@ -17458,6 +17477,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
ctx.tb = tb;
ctx.bstate = BS_NONE;
ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
+ ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
/* 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);
@@ -17840,6 +17860,8 @@ void cpu_state_reset(CPUMIPSState *env)
env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
+ env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
+ env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
env->insn_flags = env->cpu_model->insn_flags;