add MSA MI10 format instructions Signed-off-by: Yongbok Kim <yongbok....@imgtec.com> --- target-mips/helper.h | 2 + target-mips/msa_helper.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ target-mips/translate.c | 43 ++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 0 deletions(-)
diff --git a/target-mips/helper.h b/target-mips/helper.h index c86bd36..89ca4d1 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -806,6 +806,7 @@ DEF_HELPER_5(msa_ilvod_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_ilvr_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_ld_df, void, env, i32, i32, i32, s64) DEF_HELPER_4(msa_ldi_df, void, env, i32, i32, i32) DEF_HELPER_5(msa_madd_q_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32) @@ -855,6 +856,7 @@ DEF_HELPER_5(msa_srl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srli_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srlr_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) +DEF_HELPER_5(msa_st_df, void, env, i32, i32, i32, s64) DEF_HELPER_5(msa_subs_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subs_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subsus_u_df, void, env, i32, i32, i32, i32) diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c index d152953..9827dfd 100644 --- a/target-mips/msa_helper.c +++ b/target-mips/msa_helper.c @@ -3240,6 +3240,81 @@ void helper_msa_msubr_q_df(CPUMIPSState *env, uint32_t df, uint32_t wd, } } +static inline int64_t msa_ld_df(CPUMIPSState *env, uint32_t df_bits, + target_ulong addr) +{ + switch (df_bits) { + case 8: + return do_ld8(env, addr, env->hflags & MIPS_HFLAG_KSU); + case 16: + return do_ld16(env, addr, env->hflags & MIPS_HFLAG_KSU); + case 32: + return (int64_t) do_ld32(env, addr, env->hflags & MIPS_HFLAG_KSU); + case 64: + return (int64_t) do_ld64(env, addr, env->hflags & MIPS_HFLAG_KSU); + } + return 0; +} + +void helper_msa_ld_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs, + int64_t s10) +{ + int64_t td; + int df_bits = 8 * (1 << df); + int i; + target_ulong addr; + int16_t offset = s10 << df; + + for (i = 0; i < MSA_WRLEN / df_bits; i++) { + addr = env->active_tc.gpr[rs] + offset + (i << df); + td = msa_ld_df(env, df_bits, addr); + msa_store_wr_elem(env, td, wd, df, i); + } + + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + +static inline void msa_st_df(CPUMIPSState *env, uint32_t df_bits, + target_ulong addr, int64_t val) +{ + switch (df_bits) { + case 8: + do_st8(env, addr, val, env->hflags & MIPS_HFLAG_KSU); + break; + case 16: + do_st16(env, addr, val, env->hflags & MIPS_HFLAG_KSU); + break; + case 32: + do_st32(env, addr, val, env->hflags & MIPS_HFLAG_KSU); + break; + case 64: + do_st64(env, addr, val, env->hflags & MIPS_HFLAG_KSU); + break; + } +} + +void helper_msa_st_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs, + int64_t s10) +{ + int64_t td; + int df_bits = 8 * (1 << df); + int i; + target_ulong addr; + int16_t offset = s10 << df; + + for (i = 0; i < MSA_WRLEN / df_bits; i++) { + addr = env->active_tc.gpr[rs] + offset + (i << df); + td = msa_load_wr_elem_i64(env, wd, df, i); + msa_st_df(env, df_bits, addr, td); + } + + if (env->active_msa.msair & MSAIR_WRP_BIT) { + env->active_msa.msamodify |= (1 << wd); + } +} + #define FLOAT_ONE32 make_float32(0x3f8 << 20) #define FLOAT_ONE64 make_float64(0x3ffULL << 52) diff --git a/target-mips/translate.c b/target-mips/translate.c index dcfe830..7047248 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -15862,6 +15862,49 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) case OPC_MSA_VEC: gen_msa_vec(env, ctx); break; + case OPC_MSA_LD_B: + case OPC_MSA_LD_H: + case OPC_MSA_LD_W: + case OPC_MSA_LD_D: + case OPC_MSA_ST_B: + case OPC_MSA_ST_H: + case OPC_MSA_ST_W: + case OPC_MSA_ST_D: + { + int64_t s10 = (ctx->opcode >> 16) & 0x3ff /* s10 [25:16] */; + s10 = (s10 << 54) >> 54; /* sign extend s10 to 64 bits*/ + uint8_t rs = (ctx->opcode >> 11) & 0x1f /* rs [15:11] */; + uint8_t wd = (ctx->opcode >> 6) & 0x1f /* wd [10:6] */; + uint8_t df = (ctx->opcode >> 0) & 0x3 /* df [1:0] */; + + TCGv_i32 tdf = tcg_const_i32(df); + TCGv_i32 twd = tcg_const_i32(wd); + TCGv_i32 trs = tcg_const_i32(rs); + TCGv_i64 ts10 = tcg_const_i64(s10); + + switch (MASK_MSA_MINOR(opcode)) { + case OPC_MSA_LD_B: + case OPC_MSA_LD_H: + case OPC_MSA_LD_W: + case OPC_MSA_LD_D: + check_msa_access(env, ctx, -1, -1, wd); + gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10); + break; + case OPC_MSA_ST_B: + case OPC_MSA_ST_H: + case OPC_MSA_ST_W: + case OPC_MSA_ST_D: + check_msa_access(env, ctx, -1, -1, wd); + gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10); + break; + } + + tcg_temp_free_i32(twd); + tcg_temp_free_i32(tdf); + tcg_temp_free_i32(trs); + tcg_temp_free_i64(ts10); + } + break; default: MIPS_INVAL("MSA instruction"); generate_exception(ctx, EXCP_RI); -- 1.7.4