summary refs log tree commit diff stats
path: root/target-mips
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips')
-rw-r--r--target-mips/machine.c6
-rw-r--r--target-mips/op_helper.c10
-rw-r--r--target-mips/translate.c11
-rw-r--r--target-mips/translate_init.c4
4 files changed, 20 insertions, 11 deletions
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 0ba7d736db..6c76dfbe03 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -285,6 +285,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_sbe32s(f, &env->CP0_SRSConf4);
     qemu_get_sbe32s(f, &env->CP0_HWREna);
     qemu_get_betls(f, &env->CP0_BadVAddr);
+    if (version_id >= 5) {
+        qemu_get_be32s(f, &env->CP0_BadInstr);
+        qemu_get_be32s(f, &env->CP0_BadInstrP);
+    }
     qemu_get_sbe32s(f, &env->CP0_Count);
     qemu_get_betls(f, &env->CP0_EntryHi);
     qemu_get_sbe32s(f, &env->CP0_Compare);
@@ -319,8 +323,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_betls(f, &env->CP0_ErrorEPC);
     qemu_get_sbe32s(f, &env->CP0_DESAVE);
     if (version_id >= 5) {
-        qemu_get_be32s(f, &env->CP0_BadInstr);
-        qemu_get_be32s(f, &env->CP0_BadInstrP);
         for (i = 0; i < MIPS_KSCRATCH_NUM; i++) {
             qemu_get_betls(f, &env->CP0_KScratch[i]);
         }
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index ea7d95f36c..73a8e458fc 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -304,16 +304,20 @@ static inline hwaddr do_translate_address(CPUMIPSState *env,
     }
 }
 
-#define HELPER_LD_ATOMIC(name, insn)                                          \
+#define HELPER_LD_ATOMIC(name, insn, almask)                                  \
 target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
 {                                                                             \
+    if (arg & almask) {                                                       \
+        env->CP0_BadVAddr = arg;                                              \
+        helper_raise_exception(env, EXCP_AdEL);                               \
+    }                                                                         \
     env->lladdr = do_translate_address(env, arg, 0);                          \
     env->llval = do_##insn(env, arg, mem_idx);                                \
     return env->llval;                                                        \
 }
-HELPER_LD_ATOMIC(ll, lw)
+HELPER_LD_ATOMIC(ll, lw, 0x3)
 #ifdef TARGET_MIPS64
-HELPER_LD_ATOMIC(lld, ld)
+HELPER_LD_ATOMIC(lld, ld, 0x7)
 #endif
 #undef HELPER_LD_ATOMIC
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 881e7fb6d6..ca51149872 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -4947,7 +4947,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 #if defined(TARGET_MIPS64)
             if (ctx->rxi) {
                 TCGv tmp = tcg_temp_new();
-                tcg_gen_andi_tl(tmp, arg, (3ull << 62));
+                tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
                 tcg_gen_shri_tl(tmp, tmp, 32);
                 tcg_gen_or_tl(arg, arg, tmp);
                 tcg_temp_free(tmp);
@@ -5002,7 +5002,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 #if defined(TARGET_MIPS64)
             if (ctx->rxi) {
                 TCGv tmp = tcg_temp_new();
-                tcg_gen_andi_tl(tmp, arg, (3ull << 62));
+                tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
                 tcg_gen_shri_tl(tmp, tmp, 32);
                 tcg_gen_or_tl(arg, arg, tmp);
                 tcg_temp_free(tmp);
@@ -13653,7 +13653,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                target. */
             break;
         case LUI:
-            gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
+            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
             break;
         case SYNCI:
             /* Break the TB to be able to sync copied instructions
@@ -19095,6 +19095,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
     CPUMIPSState *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
+    target_ulong next_page_start;
     CPUBreakpoint *bp;
     int j, lj = -1;
     int num_insns;
@@ -19106,6 +19107,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
         qemu_log("search pc %d\n", search_pc);
 
     pc_start = tb->pc;
+    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
     ctx.singlestep_enabled = cs->singlestep_enabled;
@@ -19204,8 +19206,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
             break;
         }
 
-        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
+        if (ctx.pc >= next_page_start) {
             break;
+        }
 
         if (tcg_op_buf_full()) {
             break;
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 1543f6c388..9e8433a919 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -474,7 +474,7 @@ static const mips_def_t mips_defs[] =
         .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
-        .CP0_Status_rw_bitmask = 0x32F8FFFF,
+        .CP0_Status_rw_bitmask = 0x12F8FFFF,
         .SEGBITS = 42,
         .PABITS = 36,
         .insn_flags = CPU_MIPS64,
@@ -575,7 +575,7 @@ static const mips_def_t mips_defs[] =
         .CP0_LLAddr_shift = 4,
         .SYNCI_Step = 32,
         .CCRes = 2,
-        .CP0_Status_rw_bitmask = 0x32F8FFFF,
+        .CP0_Status_rw_bitmask = 0x12F8FFFF,
         .SEGBITS = 42,
         .PABITS = 36,
         .insn_flags = CPU_MIPS64R2,