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
