From: Philippe Mathieu-Daudé <[email protected]>

Replace runtime helpers by translation.

Replace the legacy cpu_ld/st*_data_ra() calls by
tcg_gen_qemu_ld/st() which allow to respect atomicity.

Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
 target/mips/tcg/msa_helper.h.inc |  1 -
 target/mips/tcg/msa_helper.c     | 48 --------------------------------
 target/mips/tcg/msa_translate.c  | 42 ++++++++++++++++++++++++----
 3 files changed, 36 insertions(+), 55 deletions(-)

diff --git a/target/mips/tcg/msa_helper.h.inc b/target/mips/tcg/msa_helper.h.inc
index 50a2732e916a..86a79bf804ce 100644
--- a/target/mips/tcg/msa_helper.h.inc
+++ b/target/mips/tcg/msa_helper.h.inc
@@ -436,7 +436,6 @@ DEF_HELPER_4(msa_ffint_u_df, void, env, i32, i32, i32)
 #define MSALDST_PROTO(type)                         \
 DEF_HELPER_3(msa_ld_ ## type, void, env, i32, tl)   \
 DEF_HELPER_3(msa_st_ ## type, void, env, i32, tl)
-MSALDST_PROTO(h)
 MSALDST_PROTO(w)
 MSALDST_PROTO(d)
 #undef MSALDST_PROTO
diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index 70de98050cdc..08c900785f9e 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -8226,38 +8226,11 @@ void HELPER(msa_ffint_u_df)(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 /* Element-by-element access macros */
 #define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
 
-static inline uint64_t bswap16x4(uint64_t x)
-{
-    uint64_t m = 0x00ff00ff00ff00ffull;
-    return ((x & m) << 8) | ((x >> 8) & m);
-}
-
 static inline uint64_t bswap32x2(uint64_t x)
 {
     return ror64(bswap64(x), 32);
 }
 
-void HELPER(msa_ld_h)(CPUMIPSState *env, uint32_t wd,
-                     target_ulong addr)
-{
-    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
-    uintptr_t ra = GETPC();
-    uint64_t d0, d1;
-
-    /*
-     * Load 8 bytes at a time.  Use little-endian load, then for
-     * big-endian target, we must then swap the four halfwords.
-     */
-    d0 = cpu_ldq_le_data_ra(env, addr + 0, ra);
-    d1 = cpu_ldq_le_data_ra(env, addr + 8, ra);
-    if (mips_env_is_bigendian(env)) {
-        d0 = bswap16x4(d0);
-        d1 = bswap16x4(d1);
-    }
-    pwd->d[0] = d0;
-    pwd->d[1] = d1;
-}
-
 void HELPER(msa_ld_w)(CPUMIPSState *env, uint32_t wd,
                      target_ulong addr)
 {
@@ -8315,27 +8288,6 @@ static inline void ensure_writable_pages(CPUMIPSState 
*env,
     }
 }
 
-void HELPER(msa_st_h)(CPUMIPSState *env, uint32_t wd,
-                     target_ulong addr)
-{
-    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
-    int mmu_idx = mips_env_mmu_index(env);
-    uintptr_t ra = GETPC();
-    uint64_t d0, d1;
-
-    ensure_writable_pages(env, addr, mmu_idx, ra);
-
-    /* Store 8 bytes at a time.  See helper_msa_ld_h. */
-    d0 = pwd->d[0];
-    d1 = pwd->d[1];
-    if (mips_env_is_bigendian(env)) {
-        d0 = bswap16x4(d0);
-        d1 = bswap16x4(d1);
-    }
-    cpu_stq_le_data_ra(env, addr + 0, d0, ra);
-    cpu_stq_le_data_ra(env, addr + 8, d1, ra);
-}
-
 void HELPER(msa_st_w)(CPUMIPSState *env, uint32_t wd,
                      target_ulong addr)
 {
diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index b7ca352d07b6..0c6c2f4551dc 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -754,10 +754,27 @@ TRANS(FTINT_U,  trans_msa_2rf, gen_helper_msa_ftint_u_df);
 TRANS(FFINT_S,  trans_msa_2rf, gen_helper_msa_ffint_s_df);
 TRANS(FFINT_U,  trans_msa_2rf, gen_helper_msa_ffint_u_df);
 
+/*
+ * Byte pattern: ab.cd.ef.gh -> ba.dc.fe.bg
+ */
+static void gen_bswap16x4_i64(TCGv_i64 dst, TCGv_i64 src)
+{
+    uint64_t m = 0x00ff00ff00ff00ffull;
+    TCGv_i64 t0 = tcg_temp_new_i64();
+    TCGv_i64 t1 = tcg_temp_new_i64();
+                                        /* src = abcdefgh */
+    tcg_gen_andi_i64(t0, src, m);       /*  t0 = .b.d.f.h */
+    tcg_gen_shli_i64(t0, t0, 8);        /*  t0 = b.d.f.h. */
+    tcg_gen_shri_i64(t1, src, 8);       /*  t1 = habcdefg */
+    tcg_gen_andi_i64(t1, t1, m);        /*  t1 = .a.c.e.g */
+    tcg_gen_or_i64(dst, t0, t1);        /* dst = badcfebg */
+}
+
 static bool trans_msa_ldst(DisasContext *ctx, arg_msa_i *a, bool is_load)
 {
     static const MemOp mo_atom_df[4] = {
         MO_ATOM_NONE,
+        MO_ATOM_SUBALIGN, /* Slightly stronger than required */
     };
     TCGv_i32 wd;
     TCGv_i128 t16;
@@ -778,9 +795,6 @@ static bool trans_msa_ldst(DisasContext *ctx, arg_msa_i *a, 
bool is_load)
 
     if (is_load) {
         switch (a->df) {
-        case 1:
-            gen_helper_msa_ld_h(tcg_env, wd, addr);
-            return true;
         case 2:
             gen_helper_msa_ld_w(tcg_env, wd, addr);
             return true;
@@ -790,9 +804,6 @@ static bool trans_msa_ldst(DisasContext *ctx, arg_msa_i *a, 
bool is_load)
         }
     } else {
         switch (a->df) {
-        case 1:
-            gen_helper_msa_st_h(tcg_env, wd, addr);
-            return true;
         case 2:
             gen_helper_msa_st_w(tcg_env, wd, addr);
             return true;
@@ -812,6 +823,25 @@ static bool trans_msa_ldst(DisasContext *ctx, arg_msa_i 
*a, bool is_load)
         tcg_gen_extr_i128_i64(d0, d1, t16);
     }
 
+    if (mo_endian(ctx) != MO_LE) {
+        if (!is_load) {
+            TCGv_i64 temp_d0 = tcg_temp_new_i64();
+            TCGv_i64 temp_d1 = tcg_temp_new_i64();
+
+            tcg_gen_mov_i64(temp_d0, d0);
+            tcg_gen_mov_i64(temp_d1, d1);
+            d0 = temp_d0;
+            d1 = temp_d1;
+        }
+
+        switch (a->df) {
+        case 1:
+            gen_bswap16x4_i64(d0, d0);
+            gen_bswap16x4_i64(d1, d1);
+            break;
+        }
+    }
+
     if (!is_load) {
         tcg_gen_concat_i64_i128(t16, d0, d1);
         tcg_gen_qemu_st_i128(t16, addr, ctx->mem_idx, mop);
-- 
2.55.0


Reply via email to