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/mips-defs.h2
-rw-r--r--target-mips/mips-semi.c23
-rw-r--r--target-mips/msa_helper.c6
-rw-r--r--target-mips/op_helper.c5
-rw-r--r--target-mips/translate.c15
-rw-r--r--target-mips/translate_init.c18
6 files changed, 52 insertions, 17 deletions
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 20aa87c24c..53b185ebd3 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -11,7 +11,7 @@
 #if defined(TARGET_MIPS64)
 #define TARGET_LONG_BITS 64
 #define TARGET_PHYS_ADDR_SPACE_BITS 48
-#define TARGET_VIRT_ADDR_SPACE_BITS 42
+#define TARGET_VIRT_ADDR_SPACE_BITS 48
 #else
 #define TARGET_LONG_BITS 32
 #define TARGET_PHYS_ADDR_SPACE_BITS 40
diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c
index 1162c76df9..5050940c20 100644
--- a/target-mips/mips-semi.c
+++ b/target-mips/mips-semi.c
@@ -220,6 +220,23 @@ static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
         }                                       \
     } while (0)
 
+#define GET_TARGET_STRINGS_2(p, addr, p2, addr2)        \
+    do {                                                \
+        p = lock_user_string(addr);                     \
+        if (!p) {                                       \
+            gpr[2] = -1;                                \
+            gpr[3] = EFAULT;                            \
+            goto uhi_done;                              \
+        }                                               \
+        p2 = lock_user_string(addr2);                   \
+        if (!p2) {                                      \
+            unlock_user(p, addr, 0);                    \
+            gpr[2] = -1;                                \
+            gpr[3] = EFAULT;                            \
+            goto uhi_done;                              \
+        }                                               \
+    } while (0)
+
 #define FREE_TARGET_STRING(p, gpr)              \
     do {                                        \
         unlock_user(p, gpr, 0);                 \
@@ -322,8 +339,7 @@ void helper_do_semihosting(CPUMIPSState *env)
         FREE_TARGET_STRING(p, gpr[4]);
         break;
     case UHI_assert:
-        GET_TARGET_STRING(p, gpr[4]);
-        GET_TARGET_STRING(p2, gpr[5]);
+        GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
         printf("assertion '");
         printf("\"%s\"", p);
         printf("': file \"%s\", line %d\n", p2, (int)gpr[6]);
@@ -341,8 +357,7 @@ void helper_do_semihosting(CPUMIPSState *env)
         break;
 #ifndef _WIN32
     case UHI_link:
-        GET_TARGET_STRING(p, gpr[4]);
-        GET_TARGET_STRING(p2, gpr[5]);
+        GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
         gpr[2] = link(p, p2);
         gpr[3] = errno_mips(errno);
         FREE_TARGET_STRING(p2, gpr[5]);
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 26ffdc726e..a1cb48f2a9 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -2642,6 +2642,8 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
     uint32_t i;
 
+    clear_msacsr_cause(env);
+
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
@@ -3192,6 +3194,8 @@ void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
     uint32_t i;
 
+    clear_msacsr_cause(env);
+
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
@@ -3224,6 +3228,8 @@ void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     wr_t *pws = &(env->active_fpu.fpr[ws].wr);
     uint32_t i;
 
+    clear_msacsr_cause(env);
+
     switch (df) {
     case DF_WORD:
         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 2a9ddff70f..9c28631dc1 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -661,7 +661,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
 
     /* Sync the TASID with EntryHi.  */
     cpu->CP0_EntryHi &= ~0xff;
-    cpu->CP0_EntryHi = tasid;
+    cpu->CP0_EntryHi |= tasid;
 
     compute_hflags(cpu);
 }
@@ -2154,10 +2154,9 @@ void helper_deret(CPUMIPSState *env)
     debug_pre_eret(env);
     set_pc(env, env->CP0_DEPC);
 
-    env->hflags &= MIPS_HFLAG_DM;
+    env->hflags &= ~MIPS_HFLAG_DM;
     compute_hflags(env);
     debug_post_eret(env);
-    env->lladdr = 1;
 }
 #endif /* !CONFIG_USER_ONLY */
 
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 73028572c9..d1de35ad30 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2142,6 +2142,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         break;
     case OPC_LDL:
         t1 = tcg_temp_new();
+        /* Do a byte access to possibly trigger a page
+           fault with the unaligned address.  */
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
 #ifndef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 7);
@@ -2163,6 +2166,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         break;
     case OPC_LDR:
         t1 = tcg_temp_new();
+        /* Do a byte access to possibly trigger a page
+           fault with the unaligned address.  */
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
 #ifdef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 7);
@@ -2229,6 +2235,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         break;
     case OPC_LWL:
         t1 = tcg_temp_new();
+        /* Do a byte access to possibly trigger a page
+           fault with the unaligned address.  */
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
 #ifndef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 3);
@@ -2251,6 +2260,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         break;
     case OPC_LWR:
         t1 = tcg_temp_new();
+        /* Do a byte access to possibly trigger a page
+           fault with the unaligned address.  */
+        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
 #ifdef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 3);
@@ -9552,6 +9564,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             gen_cmp_s(ctx, func-48, ft, fs, cc);
             opn = condnames[func-48];
         }
+        optype = CMPOP;
         break;
     case OPC_ADD_D:
         check_cp1_registers(ctx, fs | ft | fd);
@@ -10036,6 +10049,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             gen_cmp_d(ctx, func-48, ft, fs, cc);
             opn = condnames[func-48];
         }
+        optype = CMPOP;
         break;
     case OPC_CVT_S_D:
         check_cp1_registers(ctx, fs);
@@ -10461,6 +10475,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
             gen_cmp_ps(ctx, func-48, ft, fs, cc);
             opn = condnames[func-48];
         }
+        optype = CMPOP;
         break;
     default:
         MIPS_INVAL(opn);
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index ddfaff8052..9304e746b4 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -655,14 +655,14 @@ static const mips_def_t mips_defs[] =
                        (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
                        (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
-        .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_RXI) | (1 << CP0C3_BP) |
-                       (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_LPA) |
-                       (1U << CP0C3_M),
-        .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
-                       (3 << CP0C4_IE) | (1 << CP0C4_M),
+        .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) |
+                       (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) |
+                       (1 << CP0C3_RXI) | (1 << CP0C3_LPA),
+        .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
+                       (0xfc << CP0C4_KScrExist),
         .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB),
-        .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
-                                  (1 << CP0C5_UFE),
+        .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
+                                  (1 << CP0C5_FRE) | (1 << CP0C5_UFE),
         .CP0_LLAddr_rw_bitmask = 0,
         .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
@@ -674,9 +674,9 @@ static const mips_def_t mips_defs[] =
         .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) |
                     (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
-        .SEGBITS = 42,
+        .SEGBITS = 48,
         .PABITS = 48,
-        .insn_flags = CPU_MIPS64R6,
+        .insn_flags = CPU_MIPS64R6 | ASE_MSA,
         .mmu_type = MMU_TYPE_R4000,
     },
     {