From 9e8aed043ea3165bd79987d1aa7b891cb297b36b Mon Sep 17 00:00:00 2001 From: Mateja Marjanovic Date: Tue, 28 May 2019 19:42:09 -0400 Subject: [PATCH] target/mips: Refactor and fix INSERT. instructions The old version of the helper for the INSERT. MSA instructions has been replaced with four helpers that don't use switch, and change the endianness of the given index, when executed on a big endian host. Backports commit c1c9a10fb1f7a6782711817c167a2c20b000fc12 from qemu --- qemu/header_gen.py | 5 ++- qemu/mips.h | 5 ++- qemu/mips64.h | 5 ++- qemu/mips64el.h | 5 ++- qemu/mipsel.h | 5 ++- qemu/target/mips/helper.h | 5 ++- qemu/target/mips/msa_helper.c | 67 ++++++++++++++++++++++++++--------- qemu/target/mips/translate.c | 19 +++++++++- 8 files changed, 92 insertions(+), 24 deletions(-) diff --git a/qemu/header_gen.py b/qemu/header_gen.py index a187ad45..4519fced 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -5048,7 +5048,10 @@ mips_symbols = ( 'helper_msa_ilvl_df', 'helper_msa_ilvod_df', 'helper_msa_ilvr_df', - 'helper_msa_insert_df', + 'helper_msa_insert_b', + 'helper_msa_insert_d', + 'helper_msa_insert_h', + 'helper_msa_insert_w', 'helper_msa_insve_df', 'helper_msa_ld_df', 'helper_msa_ldi_df', diff --git a/qemu/mips.h b/qemu/mips.h index 2cbd65c7..434e35b7 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -3936,7 +3936,10 @@ #define helper_msa_ilvl_df helper_msa_ilvl_df_mips #define helper_msa_ilvod_df helper_msa_ilvod_df_mips #define helper_msa_ilvr_df helper_msa_ilvr_df_mips -#define helper_msa_insert_df helper_msa_insert_df_mips +#define helper_msa_insert_b helper_msa_insert_b_mips +#define helper_msa_insert_d helper_msa_insert_d_mips +#define helper_msa_insert_h helper_msa_insert_h_mips +#define helper_msa_insert_w helper_msa_insert_w_mips #define helper_msa_insve_df helper_msa_insve_df_mips #define helper_msa_ld_df helper_msa_ld_df_mips #define helper_msa_ldi_df helper_msa_ldi_df_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index ef3966ab..998d8dcc 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -3936,7 +3936,10 @@ #define helper_msa_ilvl_df helper_msa_ilvl_df_mips64 #define helper_msa_ilvod_df helper_msa_ilvod_df_mips64 #define helper_msa_ilvr_df helper_msa_ilvr_df_mips64 -#define helper_msa_insert_df helper_msa_insert_df_mips64 +#define helper_msa_insert_b helper_msa_insert_b_mips64 +#define helper_msa_insert_d helper_msa_insert_d_mips64 +#define helper_msa_insert_h helper_msa_insert_h_mips64 +#define helper_msa_insert_w helper_msa_insert_w_mips64 #define helper_msa_insve_df helper_msa_insve_df_mips64 #define helper_msa_ld_df helper_msa_ld_df_mips64 #define helper_msa_ldi_df helper_msa_ldi_df_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 3bbfa494..8a034451 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -3936,7 +3936,10 @@ #define helper_msa_ilvl_df helper_msa_ilvl_df_mips64el #define helper_msa_ilvod_df helper_msa_ilvod_df_mips64el #define helper_msa_ilvr_df helper_msa_ilvr_df_mips64el -#define helper_msa_insert_df helper_msa_insert_df_mips64el +#define helper_msa_insert_b helper_msa_insert_b_mips64el +#define helper_msa_insert_d helper_msa_insert_d_mips64el +#define helper_msa_insert_h helper_msa_insert_h_mips64el +#define helper_msa_insert_w helper_msa_insert_w_mips64el #define helper_msa_insve_df helper_msa_insve_df_mips64el #define helper_msa_ld_df helper_msa_ld_df_mips64el #define helper_msa_ldi_df helper_msa_ldi_df_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index be88164f..8bd0481f 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -3936,7 +3936,10 @@ #define helper_msa_ilvl_df helper_msa_ilvl_df_mipsel #define helper_msa_ilvod_df helper_msa_ilvod_df_mipsel #define helper_msa_ilvr_df helper_msa_ilvr_df_mipsel -#define helper_msa_insert_df helper_msa_insert_df_mipsel +#define helper_msa_insert_b helper_msa_insert_b_mipsel +#define helper_msa_insert_d helper_msa_insert_d_mipsel +#define helper_msa_insert_h helper_msa_insert_h_mipsel +#define helper_msa_insert_w helper_msa_insert_w_mipsel #define helper_msa_insve_df helper_msa_insve_df_mipsel #define helper_msa_ld_df helper_msa_ld_df_mipsel #define helper_msa_ldi_df helper_msa_ldi_df_mipsel diff --git a/qemu/target/mips/helper.h b/qemu/target/mips/helper.h index e5898a5a..83ac0765 100644 --- a/qemu/target/mips/helper.h +++ b/qemu/target/mips/helper.h @@ -877,7 +877,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_splati_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_3(msa_ctcmsa, void, env, tl, i32) DEF_HELPER_2(msa_cfcmsa, tl, env, i32) @@ -944,6 +943,10 @@ DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32) DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32) diff --git a/qemu/target/mips/msa_helper.c b/qemu/target/mips/msa_helper.c index 1d3eee47..45614a57 100644 --- a/qemu/target/mips/msa_helper.c +++ b/qemu/target/mips/msa_helper.c @@ -1340,28 +1340,61 @@ void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd, env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n]; } -void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd, +void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd, uint32_t rs_num, uint32_t n) { wr_t *pwd = &(env->active_fpu.fpr[wd].wr); target_ulong rs = env->active_tc.gpr[rs_num]; - - switch (df) { - case DF_BYTE: - pwd->b[n] = (int8_t)rs; - break; - case DF_HALF: - pwd->h[n] = (int16_t)rs; - break; - case DF_WORD: - pwd->w[n] = (int32_t)rs; - break; - case DF_DOUBLE: - pwd->d[n] = (int64_t)rs; - break; - default: - assert(0); + n %= 16; +#if defined(HOST_WORDS_BIGENDIAN) + if (n < 8) { + n = 8 - n - 1; + } else { + n = 24 - n - 1; } +#endif + pwd->b[n] = (int8_t)rs; +} + +void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd, + uint32_t rs_num, uint32_t n) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + target_ulong rs = env->active_tc.gpr[rs_num]; + n %= 8; +#if defined(HOST_WORDS_BIGENDIAN) + if (n < 4) { + n = 4 - n - 1; + } else { + n = 12 - n - 1; + } +#endif + pwd->h[n] = (int16_t)rs; +} + +void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd, + uint32_t rs_num, uint32_t n) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + target_ulong rs = env->active_tc.gpr[rs_num]; + n %= 4; +#if defined(HOST_WORDS_BIGENDIAN) + if (n < 2) { + n = 2 - n - 1; + } else { + n = 6 - n - 1; + } +#endif + pwd->w[n] = (int32_t)rs; +} + +void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd, + uint32_t rs_num, uint32_t n) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + target_ulong rs = env->active_tc.gpr[rs_num]; + n %= 2; + pwd->d[n] = (int64_t)rs; } void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd, diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 1c53fb4c..4ffd371f 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -28507,7 +28507,24 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df, } break; case OPC_INSERT_df: - gen_helper_msa_insert_df(tcg_ctx, tcg_ctx->cpu_env, tdf, twd, tws, tn); + switch (df) { + case DF_BYTE: + gen_helper_msa_insert_b(tcg_ctx, tcg_ctx->cpu_env, twd, tws, tn); + break; + case DF_HALF: + gen_helper_msa_insert_h(tcg_ctx, tcg_ctx->cpu_env, twd, tws, tn); + break; + case DF_WORD: + gen_helper_msa_insert_w(tcg_ctx, tcg_ctx->cpu_env, twd, tws, tn); + break; +#if defined(TARGET_MIPS64) + case DF_DOUBLE: + gen_helper_msa_insert_d(tcg_ctx, tcg_ctx->cpu_env, twd, tws, tn); + break; +#endif + default: + assert(0); + } break; } break;