From 7ba0e95bca2c78194e9ce79c8b00a886928542e3 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Tue, 24 Sep 2019 15:26:33 +0200 Subject: [PATCH 01/18] target/mips: Clean up internal.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly fix errors and warnings reported by 'checkpatch.pl -f'. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1569331602-2586-3-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/internal.h | 60 ++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/target/mips/internal.h b/target/mips/internal.h index 685e8d67e9..3f435b5e63 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -1,4 +1,5 @@ -/* mips internal definitions and helpers +/* + * MIPS internal definitions and helpers * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -9,8 +10,10 @@ #include "fpu/softfloat-helpers.h" -/* MMU types, the first four entries have the same layout as the - CP0C0_MT field. */ +/* + * MMU types, the first four entries have the same layout as the + * CP0C0_MT field. + */ enum mips_mmu_types { MMU_TYPE_NONE, MMU_TYPE_R4000, @@ -160,9 +163,11 @@ static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env) !(env->CP0_Status & (1 << CP0St_EXL)) && !(env->CP0_Status & (1 << CP0St_ERL)) && !(env->hflags & MIPS_HFLAG_DM) && - /* Note that the TCStatus IXMT field is initialized to zero, - and only MT capable cores can set it to one. So we don't - need to check for MT capabilities here. */ + /* + * Note that the TCStatus IXMT field is initialized to zero, + * and only MT capable cores can set it to one. So we don't + * need to check for MT capabilities here. + */ !(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)); } @@ -177,14 +182,18 @@ static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env) status = env->CP0_Status & CP0Ca_IP_mask; if (env->CP0_Config3 & (1 << CP0C3_VEIC)) { - /* A MIPS configured with a vectorizing external interrupt controller - will feed a vector into the Cause pending lines. The core treats - the status lines as a vector level, not as indiviual masks. */ + /* + * A MIPS configured with a vectorizing external interrupt controller + * will feed a vector into the Cause pending lines. The core treats + * the status lines as a vector level, not as indiviual masks. + */ r = pending > status; } else { - /* A MIPS configured with compatibility or VInt (Vectored Interrupts) - treats the pending lines as individual interrupt lines, the status - lines are individual masks. */ + /* + * A MIPS configured with compatibility or VInt (Vectored Interrupts) + * treats the pending lines as individual interrupt lines, the status + * lines are individual masks. + */ r = (pending & status) != 0; } return r; @@ -275,12 +284,14 @@ static inline int mips_vpe_active(CPUMIPSState *env) active = 0; } - /* Now verify that there are active thread contexts in the VPE. - - This assumes the CPU model will internally reschedule threads - if the active one goes to sleep. If there are no threads available - the active one will be in a sleeping state, and we can turn off - the entire VPE. */ + /* + * Now verify that there are active thread contexts in the VPE. + * + * This assumes the CPU model will internally reschedule threads + * if the active one goes to sleep. If there are no threads available + * the active one will be in a sleeping state, and we can turn off + * the entire VPE. + */ if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) { /* TC is not activated. */ active = 0; @@ -326,7 +337,8 @@ static inline void compute_hflags(CPUMIPSState *env) if (!(env->CP0_Status & (1 << CP0St_EXL)) && !(env->CP0_Status & (1 << CP0St_ERL)) && !(env->hflags & MIPS_HFLAG_DM)) { - env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU; + env->hflags |= (env->CP0_Status >> CP0St_KSU) & + MIPS_HFLAG_KSU; } #if defined(TARGET_MIPS64) if ((env->insn_flags & ISA_MIPS3) && @@ -403,10 +415,12 @@ static inline void compute_hflags(CPUMIPSState *env) env->hflags |= MIPS_HFLAG_COP1X; } } else if (env->insn_flags & ISA_MIPS4) { - /* All supported MIPS IV CPUs use the XX (CU3) to enable - and disable the MIPS IV extensions to the MIPS III ISA. - Some other MIPS IV CPUs ignore the bit, so the check here - would be too restrictive for them. */ + /* + * All supported MIPS IV CPUs use the XX (CU3) to enable + * and disable the MIPS IV extensions to the MIPS III ISA. + * Some other MIPS IV CPUs ignore the bit, so the check here + * would be too restrictive for them. + */ if (env->CP0_Status & (1U << CP0St_CU3)) { env->hflags |= MIPS_HFLAG_COP1X; } From f6d147bbe35c2a65a276d2fd14eb54fc6bf52419 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Tue, 24 Sep 2019 15:26:34 +0200 Subject: [PATCH 02/18] target/mips: Clean up kvm_mips.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly fix errors and warnings reported by 'checkpatch.pl -f'. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1569331602-2586-4-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/kvm_mips.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/mips/kvm_mips.h b/target/mips/kvm_mips.h index ae957f37f0..1e4014792d 100644 --- a/target/mips/kvm_mips.h +++ b/target/mips/kvm_mips.h @@ -7,7 +7,7 @@ * * Copyright (C) 2012-2014 Imagination Technologies Ltd. * Authors: Sanjay Lal -*/ + */ #ifndef KVM_MIPS_H #define KVM_MIPS_H From f823213c2233b826aeb82d1e01b3aed65c9a8c53 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Tue, 24 Sep 2019 15:26:35 +0200 Subject: [PATCH 03/18] target/mips: Clean up mips-defs.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly fix errors and warnings reported by 'checkpatch.pl -f'. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1569331602-2586-5-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/mips-defs.h | 58 +++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h index bbf056a548..a831bb4384 100644 --- a/target/mips/mips-defs.h +++ b/target/mips/mips-defs.h @@ -1,8 +1,11 @@ #ifndef QEMU_MIPS_DEFS_H #define QEMU_MIPS_DEFS_H -/* If we want to use host float regs... */ -//#define USE_HOST_FLOAT_REGS +/* + * If we want to use host float regs... + * + * #define USE_HOST_FLOAT_REGS + */ /* Real pages are variable size... */ #define MIPS_TLB_MAX 128 @@ -57,43 +60,46 @@ #define ASE_MXU 0x0200000000000000ULL /* MIPS CPU defines. */ -#define CPU_MIPS1 (ISA_MIPS1) -#define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2) -#define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) -#define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) -#define CPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) -#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) -#define CPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) -#define CPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) +#define CPU_MIPS1 (ISA_MIPS1) +#define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2) +#define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3) +#define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4) +#define CPU_VR54XX (CPU_MIPS4 | INSN_VR54XX) +#define CPU_R5900 (CPU_MIPS3 | INSN_R5900) +#define CPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E) +#define CPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F) -#define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5) +#define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5) /* MIPS Technologies "Release 1" */ -#define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32) -#define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64) +#define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32) +#define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64) /* MIPS Technologies "Release 2" */ -#define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2) -#define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2) +#define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2) +#define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2) /* MIPS Technologies "Release 3" */ -#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) -#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3) +#define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) +#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3) /* MIPS Technologies "Release 5" */ -#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) -#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5) +#define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) +#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5) /* MIPS Technologies "Release 6" */ -#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) -#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6) +#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) +#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6) /* Wave Computing: "nanoMIPS" */ -#define CPU_NANOMIPS32 (CPU_MIPS32R6 | ISA_NANOMIPS32) +#define CPU_NANOMIPS32 (CPU_MIPS32R6 | ISA_NANOMIPS32) -/* Strictly follow the architecture standard: - - Disallow "special" instruction handling for PMON/SPIM. - Note that we still maintain Count/Compare to match the host clock. */ -//#define MIPS_STRICT_STANDARD 1 +/* + * Strictly follow the architecture standard: + * - Disallow "special" instruction handling for PMON/SPIM. + * Note that we still maintain Count/Compare to match the host clock. + * + * #define MIPS_STRICT_STANDARD 1 + */ #endif /* QEMU_MIPS_DEFS_H */ From 05aa7e934b6202a3cce4154a6a50f2cdc0052071 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Tue, 24 Sep 2019 15:26:37 +0200 Subject: [PATCH 04/18] target/mips: Clean up translate.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly fix errors and warnings reported by 'checkpatch.pl -f'. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Reviewed-by: Philippe Mathieu-Daudé Message-Id: <1569331602-2586-7-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/translate.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index f2119955cf..cc5af2aaba 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -7118,7 +7118,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) tcg_gen_andi_tl(arg, arg, ~0xffff); register_name = "BadInstrX"; break; - default: + default: goto cp0_unimplemented; } break; @@ -7545,7 +7545,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_ld_tl(arg, cpu_env, - offsetof(CPUMIPSState, CP0_KScratch[sel-2])); + offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); tcg_gen_ext32s_tl(arg, arg); register_name = "KScratch"; break; @@ -8295,7 +8295,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_st_tl(arg, cpu_env, - offsetof(CPUMIPSState, CP0_KScratch[sel-2])); + offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); register_name = "KScratch"; break; default: @@ -8387,17 +8387,20 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REG01__YQMASK: CP0_CHECK(ctx->insn_flags & ASE_MT); - tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask)); + tcg_gen_ld_tl(arg, cpu_env, + offsetof(CPUMIPSState, CP0_YQMask)); register_name = "YQMask"; break; case CP0_REG01__VPESCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); - tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); + tcg_gen_ld_tl(arg, cpu_env, + offsetof(CPUMIPSState, CP0_VPESchedule)); register_name = "VPESchedule"; break; case CP0_REG01__VPESCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); - tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); + tcg_gen_ld_tl(arg, cpu_env, + offsetof(CPUMIPSState, CP0_VPEScheFBack)); register_name = "VPEScheFBack"; break; case CP0_REG01__VPEOPT: @@ -8412,7 +8415,8 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REGISTER_02: switch (sel) { case CP0_REG02__ENTRYLO0: - tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); + tcg_gen_ld_tl(arg, cpu_env, + offsetof(CPUMIPSState, CP0_EntryLo0)); register_name = "EntryLo0"; break; case CP0_REG02__TCSTATUS: @@ -8756,7 +8760,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5)); register_name = "Config5"; break; - /* 6,7 are implementation dependent */ + /* 6,7 are implementation dependent */ case CP0_REG16__CONFIG6: gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6)); register_name = "Config6"; @@ -8837,7 +8841,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) } break; case CP0_REGISTER_21: - /* Officially reserved, but sel 0 is used for R1x000 framemask */ + /* Officially reserved, but sel 0 is used for R1x000 framemask */ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6)); switch (sel) { case 0: @@ -9022,7 +9026,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case CP0_REG31__KSCRATCH6: CP0_CHECK(ctx->kscrexist & (1 << sel)); tcg_gen_ld_tl(arg, cpu_env, - offsetof(CPUMIPSState, CP0_KScratch[sel-2])); + offsetof(CPUMIPSState, CP0_KScratch[sel - 2])); register_name = "KScratch"; break; default: @@ -9112,12 +9116,14 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) break; case CP0_REG01__VPESCHEDULE: CP0_CHECK(ctx->insn_flags & ASE_MT); - tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule)); + tcg_gen_st_tl(arg, cpu_env, + offsetof(CPUMIPSState, CP0_VPESchedule)); register_name = "VPESchedule"; break; case CP0_REG01__VPESCHEFBACK: CP0_CHECK(ctx->insn_flags & ASE_MT); - tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack)); + tcg_gen_st_tl(arg, cpu_env, + offsetof(CPUMIPSState, CP0_VPEScheFBack)); register_name = "VPEScheFBack"; break; case CP0_REG01__VPEOPT: From 81c4b05995bcbeeaf7f7f4183b118a098f268d22 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:45:59 +0200 Subject: [PATCH 05/18] target/mips: msa: Split helpers for . Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-8-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 14 +++- target/mips/msa_helper.c | 170 ++++++++++++++++++++++++++++++++------- target/mips/translate.c | 30 ++++++- 3 files changed, 181 insertions(+), 33 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 51f0e1c183..d70908304f 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -777,6 +777,18 @@ DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env) DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) /* MIPS SIMD Architecture */ + +DEF_HELPER_3(msa_nloc_b, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_h, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_w, void, env, i32, i32) +DEF_HELPER_3(msa_nloc_d, void, env, i32, i32) + +DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32) +DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32) + + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_nori_b, void, env, i32, i32, i32) @@ -935,8 +947,6 @@ DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index f24061e2af..8c27c1b5bd 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -65,7 +65,147 @@ * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Bit Count group helpers here */ +static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg) +{ + uint64_t x, y; + int n, c; + + x = UNSIGNED(arg, df); + n = DF_BITS(df); + c = DF_BITS(df) / 2; + + do { + y = x >> c; + if (y != 0) { + n = n - c; + x = y; + } + c = c >> 1; + } while (c != 0); + + return n - x; +} + +static inline int64_t msa_nloc_df(uint32_t df, int64_t arg) +{ + return msa_nlzc_df(df, UNSIGNED((~arg), df)); +} + +void helper_msa_nloc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->b[0] = msa_nloc_df(DF_BYTE, pws->b[0]); + pwd->b[1] = msa_nloc_df(DF_BYTE, pws->b[1]); + pwd->b[2] = msa_nloc_df(DF_BYTE, pws->b[2]); + pwd->b[3] = msa_nloc_df(DF_BYTE, pws->b[3]); + pwd->b[4] = msa_nloc_df(DF_BYTE, pws->b[4]); + pwd->b[5] = msa_nloc_df(DF_BYTE, pws->b[5]); + pwd->b[6] = msa_nloc_df(DF_BYTE, pws->b[6]); + pwd->b[7] = msa_nloc_df(DF_BYTE, pws->b[7]); + pwd->b[8] = msa_nloc_df(DF_BYTE, pws->b[8]); + pwd->b[9] = msa_nloc_df(DF_BYTE, pws->b[9]); + pwd->b[10] = msa_nloc_df(DF_BYTE, pws->b[10]); + pwd->b[11] = msa_nloc_df(DF_BYTE, pws->b[11]); + pwd->b[12] = msa_nloc_df(DF_BYTE, pws->b[12]); + pwd->b[13] = msa_nloc_df(DF_BYTE, pws->b[13]); + pwd->b[14] = msa_nloc_df(DF_BYTE, pws->b[14]); + pwd->b[15] = msa_nloc_df(DF_BYTE, pws->b[15]); +} + +void helper_msa_nloc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->h[0] = msa_nloc_df(DF_HALF, pws->h[0]); + pwd->h[1] = msa_nloc_df(DF_HALF, pws->h[1]); + pwd->h[2] = msa_nloc_df(DF_HALF, pws->h[2]); + pwd->h[3] = msa_nloc_df(DF_HALF, pws->h[3]); + pwd->h[4] = msa_nloc_df(DF_HALF, pws->h[4]); + pwd->h[5] = msa_nloc_df(DF_HALF, pws->h[5]); + pwd->h[6] = msa_nloc_df(DF_HALF, pws->h[6]); + pwd->h[7] = msa_nloc_df(DF_HALF, pws->h[7]); +} + +void helper_msa_nloc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->w[0] = msa_nloc_df(DF_WORD, pws->w[0]); + pwd->w[1] = msa_nloc_df(DF_WORD, pws->w[1]); + pwd->w[2] = msa_nloc_df(DF_WORD, pws->w[2]); + pwd->w[3] = msa_nloc_df(DF_WORD, pws->w[3]); +} + +void helper_msa_nloc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->d[0] = msa_nloc_df(DF_DOUBLE, pws->d[0]); + pwd->d[1] = msa_nloc_df(DF_DOUBLE, pws->d[1]); +} + +void helper_msa_nlzc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->b[0] = msa_nlzc_df(DF_BYTE, pws->b[0]); + pwd->b[1] = msa_nlzc_df(DF_BYTE, pws->b[1]); + pwd->b[2] = msa_nlzc_df(DF_BYTE, pws->b[2]); + pwd->b[3] = msa_nlzc_df(DF_BYTE, pws->b[3]); + pwd->b[4] = msa_nlzc_df(DF_BYTE, pws->b[4]); + pwd->b[5] = msa_nlzc_df(DF_BYTE, pws->b[5]); + pwd->b[6] = msa_nlzc_df(DF_BYTE, pws->b[6]); + pwd->b[7] = msa_nlzc_df(DF_BYTE, pws->b[7]); + pwd->b[8] = msa_nlzc_df(DF_BYTE, pws->b[8]); + pwd->b[9] = msa_nlzc_df(DF_BYTE, pws->b[9]); + pwd->b[10] = msa_nlzc_df(DF_BYTE, pws->b[10]); + pwd->b[11] = msa_nlzc_df(DF_BYTE, pws->b[11]); + pwd->b[12] = msa_nlzc_df(DF_BYTE, pws->b[12]); + pwd->b[13] = msa_nlzc_df(DF_BYTE, pws->b[13]); + pwd->b[14] = msa_nlzc_df(DF_BYTE, pws->b[14]); + pwd->b[15] = msa_nlzc_df(DF_BYTE, pws->b[15]); +} + +void helper_msa_nlzc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->h[0] = msa_nlzc_df(DF_HALF, pws->h[0]); + pwd->h[1] = msa_nlzc_df(DF_HALF, pws->h[1]); + pwd->h[2] = msa_nlzc_df(DF_HALF, pws->h[2]); + pwd->h[3] = msa_nlzc_df(DF_HALF, pws->h[3]); + pwd->h[4] = msa_nlzc_df(DF_HALF, pws->h[4]); + pwd->h[5] = msa_nlzc_df(DF_HALF, pws->h[5]); + pwd->h[6] = msa_nlzc_df(DF_HALF, pws->h[6]); + pwd->h[7] = msa_nlzc_df(DF_HALF, pws->h[7]); +} + +void helper_msa_nlzc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->w[0] = msa_nlzc_df(DF_WORD, pws->w[0]); + pwd->w[1] = msa_nlzc_df(DF_WORD, pws->w[1]); + pwd->w[2] = msa_nlzc_df(DF_WORD, pws->w[2]); + pwd->w[3] = msa_nlzc_df(DF_WORD, pws->w[3]); +} + +void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->d[0] = msa_nlzc_df(DF_DOUBLE, pws->d[0]); + pwd->d[1] = msa_nlzc_df(DF_DOUBLE, pws->d[1]); +} /* @@ -2524,32 +2664,6 @@ static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg) return x; } -static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg) -{ - uint64_t x, y; - int n, c; - - x = UNSIGNED(arg, df); - n = DF_BITS(df); - c = DF_BITS(df) / 2; - - do { - y = x >> c; - if (y != 0) { - n = n - c; - x = y; - } - c = c >> 1; - } while (c != 0); - - return n - x; -} - -static inline int64_t msa_nloc_df(uint32_t df, int64_t arg) -{ - return msa_nlzc_df(df, UNSIGNED((~arg), df)); -} - void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs) { @@ -2633,8 +2747,6 @@ void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \ } \ } -MSA_UNOP_DF(nlzc) -MSA_UNOP_DF(nloc) MSA_UNOP_DF(pcnt) #undef MSA_UNOP_DF diff --git a/target/mips/translate.c b/target/mips/translate.c index cc5af2aaba..6de4609586 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28962,10 +28962,36 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws); break; case OPC_NLOC_df: - gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws); + switch (df) { + case DF_BYTE: + gen_helper_msa_nloc_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_nloc_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_nloc_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_nloc_d(cpu_env, twd, tws); + break; + } break; case OPC_NLZC_df: - gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws); + switch (df) { + case DF_BYTE: + gen_helper_msa_nlzc_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_nlzc_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_nlzc_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_nlzc_d(cpu_env, twd, tws); + break; + } break; default: MIPS_INVAL("MSA instruction"); From 4c5daf386fca86e64ddce8510a336551c6427cae Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:00 +0200 Subject: [PATCH 06/18] target/mips: msa: Split helpers for PCNT. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-9-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 6 +- target/mips/msa_helper.c | 143 ++++++++++++++++++++------------------- target/mips/translate.c | 19 +++++- 3 files changed, 95 insertions(+), 73 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index d70908304f..18e4c7a751 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -788,6 +788,11 @@ DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32) DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32) DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32) +DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -946,7 +951,6 @@ DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) -DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 8c27c1b5bd..fe27efc857 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -207,6 +207,80 @@ void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws) pwd->d[1] = msa_nlzc_df(DF_DOUBLE, pws->d[1]); } +static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg) +{ + uint64_t x; + + x = UNSIGNED(arg, df); + + x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL); + x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL); + x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL); + x = (x & 0x00FF00FF00FF00FFULL) + ((x >> 8) & 0x00FF00FF00FF00FFULL); + x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL); + x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32)); + + return x; +} + +void helper_msa_pcnt_b(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->b[0] = msa_pcnt_df(DF_BYTE, pws->b[0]); + pwd->b[1] = msa_pcnt_df(DF_BYTE, pws->b[1]); + pwd->b[2] = msa_pcnt_df(DF_BYTE, pws->b[2]); + pwd->b[3] = msa_pcnt_df(DF_BYTE, pws->b[3]); + pwd->b[4] = msa_pcnt_df(DF_BYTE, pws->b[4]); + pwd->b[5] = msa_pcnt_df(DF_BYTE, pws->b[5]); + pwd->b[6] = msa_pcnt_df(DF_BYTE, pws->b[6]); + pwd->b[7] = msa_pcnt_df(DF_BYTE, pws->b[7]); + pwd->b[8] = msa_pcnt_df(DF_BYTE, pws->b[8]); + pwd->b[9] = msa_pcnt_df(DF_BYTE, pws->b[9]); + pwd->b[10] = msa_pcnt_df(DF_BYTE, pws->b[10]); + pwd->b[11] = msa_pcnt_df(DF_BYTE, pws->b[11]); + pwd->b[12] = msa_pcnt_df(DF_BYTE, pws->b[12]); + pwd->b[13] = msa_pcnt_df(DF_BYTE, pws->b[13]); + pwd->b[14] = msa_pcnt_df(DF_BYTE, pws->b[14]); + pwd->b[15] = msa_pcnt_df(DF_BYTE, pws->b[15]); +} + +void helper_msa_pcnt_h(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->h[0] = msa_pcnt_df(DF_HALF, pws->h[0]); + pwd->h[1] = msa_pcnt_df(DF_HALF, pws->h[1]); + pwd->h[2] = msa_pcnt_df(DF_HALF, pws->h[2]); + pwd->h[3] = msa_pcnt_df(DF_HALF, pws->h[3]); + pwd->h[4] = msa_pcnt_df(DF_HALF, pws->h[4]); + pwd->h[5] = msa_pcnt_df(DF_HALF, pws->h[5]); + pwd->h[6] = msa_pcnt_df(DF_HALF, pws->h[6]); + pwd->h[7] = msa_pcnt_df(DF_HALF, pws->h[7]); +} + +void helper_msa_pcnt_w(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->w[0] = msa_pcnt_df(DF_WORD, pws->w[0]); + pwd->w[1] = msa_pcnt_df(DF_WORD, pws->w[1]); + pwd->w[2] = msa_pcnt_df(DF_WORD, pws->w[2]); + pwd->w[3] = msa_pcnt_df(DF_WORD, pws->w[3]); +} + +void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + pwd->d[0] = msa_pcnt_df(DF_DOUBLE, pws->d[0]); + pwd->d[1] = msa_pcnt_df(DF_DOUBLE, pws->d[1]); +} + /* * Bit Move @@ -2648,22 +2722,6 @@ void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws) msa_move_v(pwd, pws); } -static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg) -{ - uint64_t x; - - x = UNSIGNED(arg, df); - - x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL); - x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL); - x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL); - x = (x & 0x00FF00FF00FF00FFULL) + ((x >> 8) & 0x00FF00FF00FF00FFULL); - x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL); - x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32)); - - return x; -} - void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs) { @@ -2696,59 +2754,6 @@ void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd, } } -#define MSA_UNOP_DF(func) \ -void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \ - uint32_t wd, uint32_t ws) \ -{ \ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \ - wr_t *pws = &(env->active_fpu.fpr[ws].wr); \ - \ - switch (df) { \ - case DF_BYTE: \ - pwd->b[0] = msa_ ## func ## _df(df, pws->b[0]); \ - pwd->b[1] = msa_ ## func ## _df(df, pws->b[1]); \ - pwd->b[2] = msa_ ## func ## _df(df, pws->b[2]); \ - pwd->b[3] = msa_ ## func ## _df(df, pws->b[3]); \ - pwd->b[4] = msa_ ## func ## _df(df, pws->b[4]); \ - pwd->b[5] = msa_ ## func ## _df(df, pws->b[5]); \ - pwd->b[6] = msa_ ## func ## _df(df, pws->b[6]); \ - pwd->b[7] = msa_ ## func ## _df(df, pws->b[7]); \ - pwd->b[8] = msa_ ## func ## _df(df, pws->b[8]); \ - pwd->b[9] = msa_ ## func ## _df(df, pws->b[9]); \ - pwd->b[10] = msa_ ## func ## _df(df, pws->b[10]); \ - pwd->b[11] = msa_ ## func ## _df(df, pws->b[11]); \ - pwd->b[12] = msa_ ## func ## _df(df, pws->b[12]); \ - pwd->b[13] = msa_ ## func ## _df(df, pws->b[13]); \ - pwd->b[14] = msa_ ## func ## _df(df, pws->b[14]); \ - pwd->b[15] = msa_ ## func ## _df(df, pws->b[15]); \ - break; \ - case DF_HALF: \ - pwd->h[0] = msa_ ## func ## _df(df, pws->h[0]); \ - pwd->h[1] = msa_ ## func ## _df(df, pws->h[1]); \ - pwd->h[2] = msa_ ## func ## _df(df, pws->h[2]); \ - pwd->h[3] = msa_ ## func ## _df(df, pws->h[3]); \ - pwd->h[4] = msa_ ## func ## _df(df, pws->h[4]); \ - pwd->h[5] = msa_ ## func ## _df(df, pws->h[5]); \ - pwd->h[6] = msa_ ## func ## _df(df, pws->h[6]); \ - pwd->h[7] = msa_ ## func ## _df(df, pws->h[7]); \ - break; \ - case DF_WORD: \ - pwd->w[0] = msa_ ## func ## _df(df, pws->w[0]); \ - pwd->w[1] = msa_ ## func ## _df(df, pws->w[1]); \ - pwd->w[2] = msa_ ## func ## _df(df, pws->w[2]); \ - pwd->w[3] = msa_ ## func ## _df(df, pws->w[3]); \ - break; \ - case DF_DOUBLE: \ - pwd->d[0] = msa_ ## func ## _df(df, pws->d[0]); \ - pwd->d[1] = msa_ ## func ## _df(df, pws->d[1]); \ - break; \ - default: \ - assert(0); \ - } \ -} - -MSA_UNOP_DF(pcnt) -#undef MSA_UNOP_DF #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 6de4609586..0d06ba9671 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28958,9 +28958,6 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) #endif gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */ break; - case OPC_PCNT_df: - gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws); - break; case OPC_NLOC_df: switch (df) { case DF_BYTE: @@ -28993,6 +28990,22 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_PCNT_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_pcnt_b(cpu_env, twd, tws); + break; + case DF_HALF: + gen_helper_msa_pcnt_h(cpu_env, twd, tws); + break; + case DF_WORD: + gen_helper_msa_pcnt_w(cpu_env, twd, tws); + break; + case DF_DOUBLE: + gen_helper_msa_pcnt_d(cpu_env, twd, tws); + break; + } + break; default: MIPS_INVAL("MSA instruction"); generate_exception_end(ctx, EXCP_RI); From 2e3eddb0841688f233dfd9e75c69a0a3075a6899 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:01 +0200 Subject: [PATCH 07/18] target/mips: msa: Split helpers for BINS. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-10-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 10 ++ target/mips/msa_helper.c | 198 ++++++++++++++++++++++++++++++++------- target/mips/translate.c | 38 ++++++-- 3 files changed, 206 insertions(+), 40 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 18e4c7a751..93494824cd 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -793,6 +793,16 @@ DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32) DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32) DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32) +DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index fe27efc857..c9b0583664 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -301,7 +301,170 @@ void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws) * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Bit Move group helpers here */ +/* Data format bit position and unsigned values */ +#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df)) + +static inline int64_t msa_binsl_df(uint32_t df, + int64_t dest, int64_t arg1, int64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_dest = UNSIGNED(dest, df); + int32_t sh_d = BIT_POSITION(arg2, df) + 1; + int32_t sh_a = DF_BITS(df) - sh_d; + if (sh_d == DF_BITS(df)) { + return u_arg1; + } else { + return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) | + UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df); + } +} + +void helper_msa_binsl_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_binsl_df(DF_BYTE, pwd->b[0], pws->b[0], pwt->b[0]); + pwd->b[1] = msa_binsl_df(DF_BYTE, pwd->b[1], pws->b[1], pwt->b[1]); + pwd->b[2] = msa_binsl_df(DF_BYTE, pwd->b[2], pws->b[2], pwt->b[2]); + pwd->b[3] = msa_binsl_df(DF_BYTE, pwd->b[3], pws->b[3], pwt->b[3]); + pwd->b[4] = msa_binsl_df(DF_BYTE, pwd->b[4], pws->b[4], pwt->b[4]); + pwd->b[5] = msa_binsl_df(DF_BYTE, pwd->b[5], pws->b[5], pwt->b[5]); + pwd->b[6] = msa_binsl_df(DF_BYTE, pwd->b[6], pws->b[6], pwt->b[6]); + pwd->b[7] = msa_binsl_df(DF_BYTE, pwd->b[7], pws->b[7], pwt->b[7]); + pwd->b[8] = msa_binsl_df(DF_BYTE, pwd->b[8], pws->b[8], pwt->b[8]); + pwd->b[9] = msa_binsl_df(DF_BYTE, pwd->b[9], pws->b[9], pwt->b[9]); + pwd->b[10] = msa_binsl_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]); + pwd->b[11] = msa_binsl_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]); + pwd->b[12] = msa_binsl_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]); + pwd->b[13] = msa_binsl_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]); + pwd->b[14] = msa_binsl_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]); + pwd->b[15] = msa_binsl_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]); +} + +void helper_msa_binsl_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_binsl_df(DF_HALF, pwd->h[0], pws->h[0], pwt->h[0]); + pwd->h[1] = msa_binsl_df(DF_HALF, pwd->h[1], pws->h[1], pwt->h[1]); + pwd->h[2] = msa_binsl_df(DF_HALF, pwd->h[2], pws->h[2], pwt->h[2]); + pwd->h[3] = msa_binsl_df(DF_HALF, pwd->h[3], pws->h[3], pwt->h[3]); + pwd->h[4] = msa_binsl_df(DF_HALF, pwd->h[4], pws->h[4], pwt->h[4]); + pwd->h[5] = msa_binsl_df(DF_HALF, pwd->h[5], pws->h[5], pwt->h[5]); + pwd->h[6] = msa_binsl_df(DF_HALF, pwd->h[6], pws->h[6], pwt->h[6]); + pwd->h[7] = msa_binsl_df(DF_HALF, pwd->h[7], pws->h[7], pwt->h[7]); +} + +void helper_msa_binsl_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_binsl_df(DF_WORD, pwd->w[0], pws->w[0], pwt->w[0]); + pwd->w[1] = msa_binsl_df(DF_WORD, pwd->w[1], pws->w[1], pwt->w[1]); + pwd->w[2] = msa_binsl_df(DF_WORD, pwd->w[2], pws->w[2], pwt->w[2]); + pwd->w[3] = msa_binsl_df(DF_WORD, pwd->w[3], pws->w[3], pwt->w[3]); +} + +void helper_msa_binsl_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_binsl_df(DF_DOUBLE, pwd->d[0], pws->d[0], pwt->d[0]); + pwd->d[1] = msa_binsl_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_binsr_df(uint32_t df, + int64_t dest, int64_t arg1, int64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_dest = UNSIGNED(dest, df); + int32_t sh_d = BIT_POSITION(arg2, df) + 1; + int32_t sh_a = DF_BITS(df) - sh_d; + if (sh_d == DF_BITS(df)) { + return u_arg1; + } else { + return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) | + UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df); + } +} + +void helper_msa_binsr_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_binsr_df(DF_BYTE, pwd->b[0], pws->b[0], pwt->b[0]); + pwd->b[1] = msa_binsr_df(DF_BYTE, pwd->b[1], pws->b[1], pwt->b[1]); + pwd->b[2] = msa_binsr_df(DF_BYTE, pwd->b[2], pws->b[2], pwt->b[2]); + pwd->b[3] = msa_binsr_df(DF_BYTE, pwd->b[3], pws->b[3], pwt->b[3]); + pwd->b[4] = msa_binsr_df(DF_BYTE, pwd->b[4], pws->b[4], pwt->b[4]); + pwd->b[5] = msa_binsr_df(DF_BYTE, pwd->b[5], pws->b[5], pwt->b[5]); + pwd->b[6] = msa_binsr_df(DF_BYTE, pwd->b[6], pws->b[6], pwt->b[6]); + pwd->b[7] = msa_binsr_df(DF_BYTE, pwd->b[7], pws->b[7], pwt->b[7]); + pwd->b[8] = msa_binsr_df(DF_BYTE, pwd->b[8], pws->b[8], pwt->b[8]); + pwd->b[9] = msa_binsr_df(DF_BYTE, pwd->b[9], pws->b[9], pwt->b[9]); + pwd->b[10] = msa_binsr_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]); + pwd->b[11] = msa_binsr_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]); + pwd->b[12] = msa_binsr_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]); + pwd->b[13] = msa_binsr_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]); + pwd->b[14] = msa_binsr_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]); + pwd->b[15] = msa_binsr_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]); +} + +void helper_msa_binsr_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_binsr_df(DF_HALF, pwd->h[0], pws->h[0], pwt->h[0]); + pwd->h[1] = msa_binsr_df(DF_HALF, pwd->h[1], pws->h[1], pwt->h[1]); + pwd->h[2] = msa_binsr_df(DF_HALF, pwd->h[2], pws->h[2], pwt->h[2]); + pwd->h[3] = msa_binsr_df(DF_HALF, pwd->h[3], pws->h[3], pwt->h[3]); + pwd->h[4] = msa_binsr_df(DF_HALF, pwd->h[4], pws->h[4], pwt->h[4]); + pwd->h[5] = msa_binsr_df(DF_HALF, pwd->h[5], pws->h[5], pwt->h[5]); + pwd->h[6] = msa_binsr_df(DF_HALF, pwd->h[6], pws->h[6], pwt->h[6]); + pwd->h[7] = msa_binsr_df(DF_HALF, pwd->h[7], pws->h[7], pwt->h[7]); +} + +void helper_msa_binsr_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_binsr_df(DF_WORD, pwd->w[0], pws->w[0], pwt->w[0]); + pwd->w[1] = msa_binsr_df(DF_WORD, pwd->w[1], pws->w[1], pwt->w[1]); + pwd->w[2] = msa_binsr_df(DF_WORD, pwd->w[2], pws->w[2], pwt->w[2]); + pwd->w[3] = msa_binsr_df(DF_WORD, pwd->w[3], pws->w[3], pwt->w[3]); +} + +void helper_msa_binsr_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_binsr_df(DF_DOUBLE, pwd->d[0], pws->d[0], pwt->d[0]); + pwd->d[1] = msa_binsr_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]); +} /* @@ -1023,9 +1186,6 @@ void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd, } } -/* Data format bit position and unsigned values */ -#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df)) - static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2) { int32_t b_arg2 = BIT_POSITION(arg2, df); @@ -1064,36 +1224,6 @@ static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2) return UNSIGNED(arg1 ^ (1LL << b_arg2), df); } -static inline int64_t msa_binsl_df(uint32_t df, int64_t dest, int64_t arg1, - int64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_dest = UNSIGNED(dest, df); - int32_t sh_d = BIT_POSITION(arg2, df) + 1; - int32_t sh_a = DF_BITS(df) - sh_d; - if (sh_d == DF_BITS(df)) { - return u_arg1; - } else { - return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) | - UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df); - } -} - -static inline int64_t msa_binsr_df(uint32_t df, int64_t dest, int64_t arg1, - int64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_dest = UNSIGNED(dest, df); - int32_t sh_d = BIT_POSITION(arg2, df) + 1; - int32_t sh_a = DF_BITS(df) - sh_d; - if (sh_d == DF_BITS(df)) { - return u_arg1; - } else { - return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) | - UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df); - } -} - static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m) { return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) : diff --git a/target/mips/translate.c b/target/mips/translate.c index 0d06ba9671..6080c72f53 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28386,6 +28386,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) TCGv_i32 twt = tcg_const_i32(wt); switch (MASK_MSA_3R(ctx->opcode)) { + case OPC_BINSL_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_binsl_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_binsl_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_binsl_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_binsl_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BINSR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_binsr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_binsr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_binsr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_binsr_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28515,9 +28547,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_ILVR_df: gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_BINSL_df: - gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MAX_A_df: gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt); break; @@ -28530,9 +28559,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_ILVEV_df: gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_BINSR_df: - gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MIN_A_df: gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt); break; From c1ed3038e74019e8cd67536b0df9d8484b954714 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:02 +0200 Subject: [PATCH 08/18] target/mips: msa: Unroll loops and demacro .V Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-11-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 7 +++-- target/mips/msa_helper.c | 63 +++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 93494824cd..27544a1313 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -803,6 +803,10 @@ DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -957,9 +961,6 @@ DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index c9b0583664..82c8871b14 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -466,6 +466,42 @@ void helper_msa_binsr_d(CPUMIPSState *env, pwd->d[1] = msa_binsr_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]); } +void helper_msa_bmnz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = UNSIGNED( \ + ((pwd->d[0] & (~pwt->d[0])) | (pws->d[0] & pwt->d[0])), DF_DOUBLE); + pwd->d[1] = UNSIGNED( \ + ((pwd->d[1] & (~pwt->d[1])) | (pws->d[1] & pwt->d[1])), DF_DOUBLE); +} + +void helper_msa_bmz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = UNSIGNED( \ + ((pwd->d[0] & pwt->d[0]) | (pws->d[0] & (~pwt->d[0]))), DF_DOUBLE); + pwd->d[1] = UNSIGNED( \ + ((pwd->d[1] & pwt->d[1]) | (pws->d[1] & (~pwt->d[1]))), DF_DOUBLE); +} + +void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = UNSIGNED( \ + (pws->d[0] & (~pwd->d[0])) | (pwt->d[0] & pwd->d[0]), DF_DOUBLE); + pwd->d[1] = UNSIGNED( \ + (pws->d[1] & (~pwd->d[1])) | (pwt->d[1] & pwd->d[1]), DF_DOUBLE); +} + /* * Bit Set @@ -946,6 +982,9 @@ MSA_FN_IMM8(bmzi_b, pwd->b[i], MSA_FN_IMM8(bseli_b, pwd->b[i], BIT_SELECT(pwd->b[i], pws->b[i], i8, DF_BYTE)) +#undef BIT_SELECT +#undef BIT_MOVE_IF_ZERO +#undef BIT_MOVE_IF_NOT_ZERO #undef MSA_FN_IMM8 #define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03)) @@ -980,30 +1019,6 @@ void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd, msa_move_v(pwd, pwx); } -#define MSA_FN_VECTOR(FUNC, DEST, OPERATION) \ -void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws, \ - uint32_t wt) \ -{ \ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \ - wr_t *pws = &(env->active_fpu.fpr[ws].wr); \ - wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \ - uint32_t i; \ - for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \ - DEST = OPERATION; \ - } \ -} - -MSA_FN_VECTOR(bmnz_v, pwd->d[i], - BIT_MOVE_IF_NOT_ZERO(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE)) -MSA_FN_VECTOR(bmz_v, pwd->d[i], - BIT_MOVE_IF_ZERO(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE)) -MSA_FN_VECTOR(bsel_v, pwd->d[i], - BIT_SELECT(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE)) -#undef BIT_MOVE_IF_NOT_ZERO -#undef BIT_MOVE_IF_ZERO -#undef BIT_SELECT -#undef MSA_FN_VECTOR - void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) { wr_t *pwd = &(env->active_fpu.fpr[wd].wr); From a44d6d14a12d3410628ef4ec0e27089670d218d0 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:03 +0200 Subject: [PATCH 09/18] target/mips: msa: Split helpers for B. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-12-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 18 +++- target/mips/msa_helper.c | 227 +++++++++++++++++++++++++++++++++++---- target/mips/translate.c | 57 ++++++++-- 3 files changed, 267 insertions(+), 35 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 27544a1313..1411e0e494 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -807,6 +807,21 @@ DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -846,9 +861,6 @@ DEF_HELPER_5(msa_srlri_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_sll_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_sra_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_srl_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bclr_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bset_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_bneg_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsl_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_binsr_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_addv_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 82c8871b14..5177e41a09 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -523,7 +523,210 @@ void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Bit Set group helpers here */ +static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + int32_t b_arg2 = BIT_POSITION(arg2, df); + return UNSIGNED(arg1 & (~(1LL << b_arg2)), df); +} + +void helper_msa_bclr_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_bclr_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_bclr_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_bclr_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_bclr_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_bclr_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_bclr_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_bclr_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_bclr_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_bclr_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_bclr_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_bclr_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_bclr_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_bclr_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_bclr_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_bclr_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_bclr_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_bclr_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_bclr_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_bclr_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_bclr_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_bclr_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_bclr_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_bclr_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_bclr_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_bclr_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_bclr_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_bclr_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_bclr_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_bclr_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_bclr_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_bclr_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_bclr_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + int32_t b_arg2 = BIT_POSITION(arg2, df); + return UNSIGNED(arg1 ^ (1LL << b_arg2), df); +} + +void helper_msa_bneg_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_bneg_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_bneg_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_bneg_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_bneg_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_bneg_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_bneg_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_bneg_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_bneg_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_bneg_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_bneg_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_bneg_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_bneg_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_bneg_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_bneg_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_bneg_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_bneg_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_bneg_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_bneg_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_bneg_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_bneg_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_bneg_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_bneg_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_bneg_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_bneg_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_bneg_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_bneg_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_bneg_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_bneg_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_bneg_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_bneg_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_bneg_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_bneg_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_bset_df(uint32_t df, int64_t arg1, + int64_t arg2) +{ + int32_t b_arg2 = BIT_POSITION(arg2, df); + return UNSIGNED(arg1 | (1LL << b_arg2), df); +} + +void helper_msa_bset_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_bset_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_bset_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_bset_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_bset_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_bset_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_bset_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_bset_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_bset_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_bset_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_bset_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_bset_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_bset_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_bset_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_bset_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_bset_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_bset_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_bset_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_bset_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_bset_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_bset_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_bset_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_bset_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_bset_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_bset_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_bset_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_bset_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_bset_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_bset_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_bset_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_bset_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_bset_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_bset_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} /* @@ -1220,25 +1423,6 @@ static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2) return u_arg1 >> b_arg2; } -static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - int32_t b_arg2 = BIT_POSITION(arg2, df); - return UNSIGNED(arg1 & (~(1LL << b_arg2)), df); -} - -static inline int64_t msa_bset_df(uint32_t df, int64_t arg1, - int64_t arg2) -{ - int32_t b_arg2 = BIT_POSITION(arg2, df); - return UNSIGNED(arg1 | (1LL << b_arg2), df); -} - -static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - int32_t b_arg2 = BIT_POSITION(arg2, df); - return UNSIGNED(arg1 ^ (1LL << b_arg2), df); -} - static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m) { return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) : @@ -1734,9 +1918,6 @@ void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \ MSA_BINOP_DF(sll) MSA_BINOP_DF(sra) MSA_BINOP_DF(srl) -MSA_BINOP_DF(bclr) -MSA_BINOP_DF(bset) -MSA_BINOP_DF(bneg) MSA_BINOP_DF(addv) MSA_BINOP_DF(subv) MSA_BINOP_DF(max_s) diff --git a/target/mips/translate.c b/target/mips/translate.c index 6080c72f53..1a87f79b7e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28418,6 +28418,54 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_BCLR_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bclr_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bclr_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bclr_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bclr_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BNEG_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bneg_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bneg_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bneg_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bneg_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_BSET_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_bset_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_bset_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_bset_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_bset_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28487,9 +28535,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_SRLR_df: gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_BCLR_df: - gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MAX_U_df: gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt); break; @@ -28505,9 +28550,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_PCKOD_df: gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_BSET_df: - gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MIN_S_df: gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt); break; @@ -28526,9 +28568,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_ILVL_df: gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_BNEG_df: - gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MIN_U_df: gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt); break; From 7672edc4c60dde5b1709ee223fbaeefd14519a8f Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:04 +0200 Subject: [PATCH 10/18] target/mips: msa: Split helpers for AVE_. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-13-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 12 ++- target/mips/msa_helper.c | 162 +++++++++++++++++++++++++++++++++++---- target/mips/translate.c | 38 +++++++-- 3 files changed, 187 insertions(+), 25 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 1411e0e494..455dd25841 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -822,6 +822,16 @@ DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -880,8 +890,6 @@ DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ave_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ave_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_aver_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_aver_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_subs_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 5177e41a09..1a7f90c713 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -832,7 +832,151 @@ void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Int Average group helpers here */ +static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + /* signed shift */ + return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1); +} + +void helper_msa_ave_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_ave_s_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_ave_s_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_ave_s_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_ave_s_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_ave_s_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_ave_s_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_ave_s_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_ave_s_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_ave_s_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_ave_s_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_ave_s_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_ave_s_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_ave_s_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_ave_s_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_ave_s_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_ave_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_ave_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_ave_s_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_ave_s_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_ave_s_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_ave_s_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_ave_s_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_ave_s_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_ave_s_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_ave_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_ave_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_ave_s_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_ave_s_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_ave_s_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_ave_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_ave_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_ave_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_ave_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_arg2 = UNSIGNED(arg2, df); + /* unsigned shift */ + return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1); +} + +void helper_msa_ave_u_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_ave_u_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_ave_u_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_ave_u_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_ave_u_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_ave_u_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_ave_u_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_ave_u_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_ave_u_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_ave_u_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_ave_u_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_ave_u_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_ave_u_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_ave_u_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_ave_u_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_ave_u_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_ave_u_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_ave_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_ave_u_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_ave_u_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_ave_u_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_ave_u_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_ave_u_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_ave_u_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_ave_u_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_ave_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_ave_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_ave_u_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_ave_u_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_ave_u_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_ave_u_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_ave_u_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_ave_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_ave_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} /* @@ -1600,20 +1744,6 @@ static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2) return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint; } -static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - /* signed shift */ - return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1); -} - -static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_arg2 = UNSIGNED(arg2, df); - /* unsigned shift */ - return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1); -} - static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2) { /* signed shift */ @@ -1935,8 +2065,6 @@ MSA_BINOP_DF(add_a) MSA_BINOP_DF(adds_a) MSA_BINOP_DF(adds_s) MSA_BINOP_DF(adds_u) -MSA_BINOP_DF(ave_s) -MSA_BINOP_DF(ave_u) MSA_BINOP_DF(aver_s) MSA_BINOP_DF(aver_u) MSA_BINOP_DF(subs_s) diff --git a/target/mips/translate.c b/target/mips/translate.c index 1a87f79b7e..2b0abbbe7b 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28466,6 +28466,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_AVE_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVE_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28556,9 +28588,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_CLE_S_df: gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_AVE_S_df: - gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ASUB_S_df: gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt); break; @@ -28574,9 +28603,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_CLE_U_df: gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_AVE_U_df: - gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ASUB_U_df: gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt); break; From 755107e226ca0078a0d41ca06392ca253cbcd224 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:05 +0200 Subject: [PATCH 11/18] target/mips: msa: Split helpers for AVER_. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-14-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 12 ++- target/mips/msa_helper.c | 162 +++++++++++++++++++++++++++++++++++---- target/mips/translate.c | 38 +++++++-- 3 files changed, 188 insertions(+), 24 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 455dd25841..9d4c9f1097 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -832,6 +832,16 @@ DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -890,8 +900,6 @@ DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_aver_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_aver_u_df, void, env, i32, i32, i32, i32) 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 1a7f90c713..17443b9981 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -978,6 +978,152 @@ void helper_msa_ave_u_d(CPUMIPSState *env, pwd->d[1] = msa_ave_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); } +static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + /* signed shift */ + return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1); +} + +void helper_msa_aver_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_aver_s_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_aver_s_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_aver_s_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_aver_s_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_aver_s_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_aver_s_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_aver_s_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_aver_s_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_aver_s_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_aver_s_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_aver_s_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_aver_s_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_aver_s_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_aver_s_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_aver_s_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_aver_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_aver_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_aver_s_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_aver_s_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_aver_s_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_aver_s_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_aver_s_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_aver_s_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_aver_s_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_aver_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_aver_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_aver_s_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_aver_s_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_aver_s_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_aver_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_aver_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_aver_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_aver_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_arg2 = UNSIGNED(arg2, df); + /* unsigned shift */ + return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1); +} + +void helper_msa_aver_u_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_aver_u_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_aver_u_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_aver_u_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_aver_u_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_aver_u_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_aver_u_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_aver_u_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_aver_u_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_aver_u_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_aver_u_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_aver_u_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_aver_u_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_aver_u_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_aver_u_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_aver_u_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_aver_u_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_aver_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_aver_u_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_aver_u_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_aver_u_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_aver_u_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_aver_u_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_aver_u_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_aver_u_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_aver_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_aver_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_aver_u_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_aver_u_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_aver_u_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_aver_u_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_aver_u_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_aver_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_aver_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + /* * Int Compare @@ -1744,20 +1890,6 @@ static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2) return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint; } -static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - /* signed shift */ - return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1); -} - -static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_arg2 = UNSIGNED(arg2, df); - /* unsigned shift */ - return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1); -} - static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2) { int64_t max_int = DF_MAX_INT(df); @@ -2065,8 +2197,6 @@ MSA_BINOP_DF(add_a) MSA_BINOP_DF(adds_a) MSA_BINOP_DF(adds_s) MSA_BINOP_DF(adds_u) -MSA_BINOP_DF(aver_s) -MSA_BINOP_DF(aver_u) MSA_BINOP_DF(subs_s) MSA_BINOP_DF(subs_u) MSA_BINOP_DF(subsus_u) diff --git a/target/mips/translate.c b/target/mips/translate.c index 2b0abbbe7b..9b186d3cb6 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28498,6 +28498,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_AVER_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_AVER_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28615,9 +28647,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MAX_A_df: gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_AVER_S_df: - gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MOD_S_df: gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt); break; @@ -28627,9 +28656,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MIN_A_df: gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_AVER_U_df: - gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_MOD_U_df: gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt); break; From ade7e788e1e19868d9e66aaa79e134362b671b11 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:06 +0200 Subject: [PATCH 12/18] target/mips: msa: Split helpers for CEQ. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-15-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 6 +++- target/mips/msa_helper.c | 73 ++++++++++++++++++++++++++++++++++++---- target/mips/translate.c | 19 +++++++++-- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 9d4c9f1097..95eb065456 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -842,6 +842,11 @@ DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -891,7 +896,6 @@ DEF_HELPER_5(msa_min_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_max_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_ceq_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_clt_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_clt_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_cle_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 17443b9981..c8c6cdb59d 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1153,7 +1153,72 @@ void helper_msa_aver_u_d(CPUMIPSState *env, * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Int Compare group helpers here */ +static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + return arg1 == arg2 ? -1 : 0; +} + +void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_ceq_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_ceq_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_ceq_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_ceq_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_ceq_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_ceq_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_ceq_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_ceq_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_ceq_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_ceq_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_ceq_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_ceq_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_ceq_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_ceq_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_ceq_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_ceq_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_ceq_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_ceq_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_ceq_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_ceq_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_ceq_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_ceq_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_ceq_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_ceq_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_ceq_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_ceq_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_ceq_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_ceq_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_ceq_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_ceq_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} /* @@ -1562,11 +1627,6 @@ static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2) return arg1 - arg2; } -static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - return arg1 == arg2 ? -1 : 0; -} - static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2) { return arg1 <= arg2 ? -1 : 0; @@ -2188,7 +2248,6 @@ MSA_BINOP_DF(min_s) MSA_BINOP_DF(min_u) MSA_BINOP_DF(max_a) MSA_BINOP_DF(min_a) -MSA_BINOP_DF(ceq) MSA_BINOP_DF(clt_s) MSA_BINOP_DF(clt_u) MSA_BINOP_DF(cle_s) diff --git a/target/mips/translate.c b/target/mips/translate.c index 9b186d3cb6..ad1572e959 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28530,15 +28530,28 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_CEQ_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_ceq_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_ceq_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_ceq_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_ceq_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; case OPC_ADDV_df: gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_CEQ_df: - gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ADD_A_df: gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt); break; From 0501bb1a6662a47dd7f3fa82109e28bb7f67c6fd Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:07 +0200 Subject: [PATCH 13/18] target/mips: msa: Split helpers for CLE_. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-16-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 12 ++- target/mips/msa_helper.c | 158 +++++++++++++++++++++++++++++++++++---- target/mips/translate.c | 38 ++++++++-- 3 files changed, 186 insertions(+), 22 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 95eb065456..32ff24b0c1 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -847,6 +847,16 @@ DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_ceq_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_cle_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_cle_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -898,8 +908,6 @@ DEF_HELPER_5(msa_max_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_clt_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_clt_u_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_cle_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_cle_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index c8c6cdb59d..d696791452 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1220,6 +1220,150 @@ void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) pwd->d[1] = msa_ceq_df(DF_DOUBLE, pws->d[1], pwt->d[1]); } +static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + return arg1 <= arg2 ? -1 : 0; +} + +void helper_msa_cle_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_cle_s_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_cle_s_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_cle_s_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_cle_s_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_cle_s_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_cle_s_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_cle_s_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_cle_s_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_cle_s_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_cle_s_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_cle_s_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_cle_s_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_cle_s_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_cle_s_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_cle_s_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_cle_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_cle_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_cle_s_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_cle_s_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_cle_s_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_cle_s_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_cle_s_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_cle_s_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_cle_s_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_cle_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_cle_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_cle_s_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_cle_s_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_cle_s_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_cle_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_cle_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_cle_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_cle_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_arg2 = UNSIGNED(arg2, df); + return u_arg1 <= u_arg2 ? -1 : 0; +} + +void helper_msa_cle_u_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_cle_u_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_cle_u_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_cle_u_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_cle_u_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_cle_u_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_cle_u_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_cle_u_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_cle_u_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_cle_u_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_cle_u_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_cle_u_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_cle_u_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_cle_u_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_cle_u_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_cle_u_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_cle_u_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_cle_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_cle_u_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_cle_u_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_cle_u_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_cle_u_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_cle_u_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_cle_u_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_cle_u_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_cle_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_cle_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_cle_u_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_cle_u_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_cle_u_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_cle_u_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_cle_u_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_cle_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_cle_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + /* * Int Divide @@ -1627,18 +1771,6 @@ static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2) return arg1 - arg2; } -static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - return arg1 <= arg2 ? -1 : 0; -} - -static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_arg2 = UNSIGNED(arg2, df); - return u_arg1 <= u_arg2 ? -1 : 0; -} - static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2) { return arg1 < arg2 ? -1 : 0; @@ -2250,8 +2382,6 @@ MSA_BINOP_DF(max_a) MSA_BINOP_DF(min_a) MSA_BINOP_DF(clt_s) MSA_BINOP_DF(clt_u) -MSA_BINOP_DF(cle_s) -MSA_BINOP_DF(cle_u) MSA_BINOP_DF(add_a) MSA_BINOP_DF(adds_a) MSA_BINOP_DF(adds_s) diff --git a/target/mips/translate.c b/target/mips/translate.c index ad1572e959..614b9e7cb3 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28546,6 +28546,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_CLE_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLE_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28630,9 +28662,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MIN_S_df: gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_CLE_S_df: - gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ASUB_S_df: gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt); break; @@ -28645,9 +28674,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MIN_U_df: gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_CLE_U_df: - gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ASUB_U_df: gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt); break; From 1165669982b1ca3ca62d7091f17669d83e46e8b9 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:08 +0200 Subject: [PATCH 14/18] target/mips: msa: Split helpers for CLT_. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-17-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 12 ++- target/mips/msa_helper.c | 158 +++++++++++++++++++++++++++++++++++---- target/mips/translate.c | 38 ++++++++-- 3 files changed, 186 insertions(+), 22 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 32ff24b0c1..29dfcf070b 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -857,6 +857,16 @@ DEF_HELPER_4(msa_cle_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_cle_u_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_cle_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_clt_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_clt_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -906,8 +916,6 @@ DEF_HELPER_5(msa_min_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_max_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_min_a_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_clt_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_clt_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_add_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_a_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_adds_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index d696791452..b658f48e04 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1364,6 +1364,150 @@ void helper_msa_cle_u_d(CPUMIPSState *env, pwd->d[1] = msa_cle_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); } +static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + return arg1 < arg2 ? -1 : 0; +} + +void helper_msa_clt_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_clt_s_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_clt_s_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_clt_s_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_clt_s_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_clt_s_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_clt_s_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_clt_s_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_clt_s_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_clt_s_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_clt_s_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_clt_s_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_clt_s_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_clt_s_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_clt_s_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_clt_s_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_clt_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_clt_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_clt_s_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_clt_s_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_clt_s_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_clt_s_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_clt_s_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_clt_s_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_clt_s_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_clt_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_clt_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_clt_s_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_clt_s_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_clt_s_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_clt_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_clt_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_clt_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_clt_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_arg2 = UNSIGNED(arg2, df); + return u_arg1 < u_arg2 ? -1 : 0; +} + +void helper_msa_clt_u_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_clt_u_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_clt_u_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_clt_u_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_clt_u_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_clt_u_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_clt_u_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_clt_u_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_clt_u_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_clt_u_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_clt_u_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_clt_u_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_clt_u_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_clt_u_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_clt_u_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_clt_u_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_clt_u_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_clt_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_clt_u_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_clt_u_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_clt_u_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_clt_u_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_clt_u_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_clt_u_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_clt_u_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_clt_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_clt_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_clt_u_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_clt_u_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_clt_u_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_clt_u_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_clt_u_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_clt_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_clt_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + /* * Int Divide @@ -1771,18 +1915,6 @@ static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2) return arg1 - arg2; } -static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - return arg1 < arg2 ? -1 : 0; -} - -static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_arg2 = UNSIGNED(arg2, df); - return u_arg1 < u_arg2 ? -1 : 0; -} - static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2) { return arg1 > arg2 ? arg1 : arg2; @@ -2380,8 +2512,6 @@ MSA_BINOP_DF(min_s) MSA_BINOP_DF(min_u) MSA_BINOP_DF(max_a) MSA_BINOP_DF(min_a) -MSA_BINOP_DF(clt_s) -MSA_BINOP_DF(clt_u) MSA_BINOP_DF(add_a) MSA_BINOP_DF(adds_a) MSA_BINOP_DF(adds_s) diff --git a/target/mips/translate.c b/target/mips/translate.c index 614b9e7cb3..4db87d637e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28578,6 +28578,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_CLT_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_CLT_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28626,9 +28658,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MAX_S_df: gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_CLT_S_df: - gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ADDS_S_df: gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt); break; @@ -28647,9 +28676,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MAX_U_df: gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_CLT_U_df: - gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ADDS_U_df: gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt); break; From 64a0257f1fc3fd45984b04a4c93d6bfd4cebb97c Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:09 +0200 Subject: [PATCH 15/18] target/mips: msa: Split helpers for DIV_. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-18-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 12 ++- target/mips/msa_helper.c | 167 ++++++++++++++++++++++++++++++++++----- target/mips/translate.c | 38 +++++++-- 3 files changed, 190 insertions(+), 27 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 29dfcf070b..ec4982f5fc 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -867,6 +867,16 @@ DEF_HELPER_4(msa_clt_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_clt_u_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_clt_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_s_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_div_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -929,8 +939,6 @@ DEF_HELPER_5(msa_asub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_mulv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_maddv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_msubv_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_div_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_div_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_mod_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_mod_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_dotp_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index b658f48e04..ceccd8f9be 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1525,7 +1525,154 @@ void helper_msa_clt_u_d(CPUMIPSState *env, * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Int Divide group helpers here */ + +static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + if (arg1 == DF_MIN_INT(df) && arg2 == -1) { + return DF_MIN_INT(df); + } + return arg2 ? arg1 / arg2 + : arg1 >= 0 ? -1 : 1; +} + +void helper_msa_div_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_div_s_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_div_s_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_div_s_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_div_s_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_div_s_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_div_s_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_div_s_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_div_s_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_div_s_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_div_s_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_div_s_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_div_s_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_div_s_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_div_s_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_div_s_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_div_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_div_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_div_s_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_div_s_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_div_s_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_div_s_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_div_s_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_div_s_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_div_s_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_div_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_div_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_div_s_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_div_s_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_div_s_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_div_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_div_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_div_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_div_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_arg2 = UNSIGNED(arg2, df); + return arg2 ? u_arg1 / u_arg2 : -1; +} + +void helper_msa_div_u_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_div_u_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_div_u_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_div_u_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_div_u_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_div_u_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_div_u_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_div_u_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_div_u_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_div_u_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_div_u_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_div_u_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_div_u_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_div_u_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_div_u_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_div_u_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_div_u_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_div_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_div_u_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_div_u_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_div_u_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_div_u_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_div_u_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_div_u_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_div_u_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_div_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_div_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_div_u_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_div_u_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_div_u_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_div_u_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_div_u_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_div_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_div_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} /* @@ -2287,22 +2434,6 @@ static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2) return arg1 * arg2; } -static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - if (arg1 == DF_MIN_INT(df) && arg2 == -1) { - return DF_MIN_INT(df); - } - return arg2 ? arg1 / arg2 - : arg1 >= 0 ? -1 : 1; -} - -static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_arg2 = UNSIGNED(arg2, df); - return arg2 ? u_arg1 / u_arg2 : -1; -} - static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2) { if (arg1 == DF_MIN_INT(df) && arg2 == -1) { @@ -2523,8 +2654,6 @@ MSA_BINOP_DF(subsuu_s) MSA_BINOP_DF(asub_s) MSA_BINOP_DF(asub_u) MSA_BINOP_DF(mulv) -MSA_BINOP_DF(div_s) -MSA_BINOP_DF(div_u) MSA_BINOP_DF(mod_s) MSA_BINOP_DF(mod_u) MSA_BINOP_DF(dotp_s) diff --git a/target/mips/translate.c b/target/mips/translate.c index 4db87d637e..27eca0aa3e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28610,6 +28610,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_DIV_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_div_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_div_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_div_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_div_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_DIV_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_div_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_div_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_div_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_div_u_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28691,9 +28723,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_ASUB_S_df: gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_DIV_S_df: - gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ILVL_df: gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt); break; @@ -28703,9 +28732,6 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_ASUB_U_df: gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_DIV_U_df: - gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ILVR_df: gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt); break; From a6387ea5dee38170c62233d1cc80dd16d8f3d8e8 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:10 +0200 Subject: [PATCH 16/18] target/mips: msa: Split helpers for MOD_. Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-19-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 12 ++- target/mips/msa_helper.c | 164 ++++++++++++++++++++++++++++++++++----- target/mips/translate.c | 38 +++++++-- 3 files changed, 188 insertions(+), 26 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index ec4982f5fc..cc216f7ae5 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -877,6 +877,16 @@ DEF_HELPER_4(msa_div_u_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_div_u_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_div_u_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_u_d, void, env, i32, i32, i32) + +DEF_HELPER_4(msa_mod_s_b, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) +DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) + DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -939,8 +949,6 @@ DEF_HELPER_5(msa_asub_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_mulv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_maddv_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_msubv_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_mod_s_df, void, env, i32, i32, i32, i32) -DEF_HELPER_5(msa_mod_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_dotp_s_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_dotp_u_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_dpadd_s_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index ceccd8f9be..04fee66042 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -1755,7 +1755,152 @@ void helper_msa_div_u_d(CPUMIPSState *env, * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Int Modulo group helpers here */ +static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + if (arg1 == DF_MIN_INT(df) && arg2 == -1) { + return 0; + } + return arg2 ? arg1 % arg2 : arg1; +} + +void helper_msa_mod_s_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_mod_s_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_mod_s_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_mod_s_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_mod_s_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_mod_s_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_mod_s_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_mod_s_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_mod_s_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_mod_s_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_mod_s_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_mod_s_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_mod_s_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_mod_s_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_mod_s_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_mod_s_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_mod_s_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_mod_s_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_mod_s_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_mod_s_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_mod_s_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_mod_s_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_mod_s_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_mod_s_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_mod_s_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_mod_s_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_mod_s_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_mod_s_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_mod_s_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_mod_s_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_mod_s_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_mod_s_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_mod_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_mod_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} + +static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2) +{ + uint64_t u_arg1 = UNSIGNED(arg1, df); + uint64_t u_arg2 = UNSIGNED(arg2, df); + return u_arg2 ? u_arg1 % u_arg2 : u_arg1; +} + +void helper_msa_mod_u_b(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->b[0] = msa_mod_u_df(DF_BYTE, pws->b[0], pwt->b[0]); + pwd->b[1] = msa_mod_u_df(DF_BYTE, pws->b[1], pwt->b[1]); + pwd->b[2] = msa_mod_u_df(DF_BYTE, pws->b[2], pwt->b[2]); + pwd->b[3] = msa_mod_u_df(DF_BYTE, pws->b[3], pwt->b[3]); + pwd->b[4] = msa_mod_u_df(DF_BYTE, pws->b[4], pwt->b[4]); + pwd->b[5] = msa_mod_u_df(DF_BYTE, pws->b[5], pwt->b[5]); + pwd->b[6] = msa_mod_u_df(DF_BYTE, pws->b[6], pwt->b[6]); + pwd->b[7] = msa_mod_u_df(DF_BYTE, pws->b[7], pwt->b[7]); + pwd->b[8] = msa_mod_u_df(DF_BYTE, pws->b[8], pwt->b[8]); + pwd->b[9] = msa_mod_u_df(DF_BYTE, pws->b[9], pwt->b[9]); + pwd->b[10] = msa_mod_u_df(DF_BYTE, pws->b[10], pwt->b[10]); + pwd->b[11] = msa_mod_u_df(DF_BYTE, pws->b[11], pwt->b[11]); + pwd->b[12] = msa_mod_u_df(DF_BYTE, pws->b[12], pwt->b[12]); + pwd->b[13] = msa_mod_u_df(DF_BYTE, pws->b[13], pwt->b[13]); + pwd->b[14] = msa_mod_u_df(DF_BYTE, pws->b[14], pwt->b[14]); + pwd->b[15] = msa_mod_u_df(DF_BYTE, pws->b[15], pwt->b[15]); +} + +void helper_msa_mod_u_h(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->h[0] = msa_mod_u_df(DF_HALF, pws->h[0], pwt->h[0]); + pwd->h[1] = msa_mod_u_df(DF_HALF, pws->h[1], pwt->h[1]); + pwd->h[2] = msa_mod_u_df(DF_HALF, pws->h[2], pwt->h[2]); + pwd->h[3] = msa_mod_u_df(DF_HALF, pws->h[3], pwt->h[3]); + pwd->h[4] = msa_mod_u_df(DF_HALF, pws->h[4], pwt->h[4]); + pwd->h[5] = msa_mod_u_df(DF_HALF, pws->h[5], pwt->h[5]); + pwd->h[6] = msa_mod_u_df(DF_HALF, pws->h[6], pwt->h[6]); + pwd->h[7] = msa_mod_u_df(DF_HALF, pws->h[7], pwt->h[7]); +} + +void helper_msa_mod_u_w(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->w[0] = msa_mod_u_df(DF_WORD, pws->w[0], pwt->w[0]); + pwd->w[1] = msa_mod_u_df(DF_WORD, pws->w[1], pwt->w[1]); + pwd->w[2] = msa_mod_u_df(DF_WORD, pws->w[2], pwt->w[2]); + pwd->w[3] = msa_mod_u_df(DF_WORD, pws->w[3], pwt->w[3]); +} + +void helper_msa_mod_u_d(CPUMIPSState *env, + uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = msa_mod_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]); + pwd->d[1] = msa_mod_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]); +} /* @@ -2434,21 +2579,6 @@ static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2) return arg1 * arg2; } -static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - if (arg1 == DF_MIN_INT(df) && arg2 == -1) { - return 0; - } - return arg2 ? arg1 % arg2 : arg1; -} - -static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2) -{ - uint64_t u_arg1 = UNSIGNED(arg1, df); - uint64_t u_arg2 = UNSIGNED(arg2, df); - return u_arg2 ? u_arg1 % u_arg2 : u_arg1; -} - #define SIGNED_EVEN(a, df) \ ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2)) @@ -2654,8 +2784,6 @@ MSA_BINOP_DF(subsuu_s) MSA_BINOP_DF(asub_s) MSA_BINOP_DF(asub_u) MSA_BINOP_DF(mulv) -MSA_BINOP_DF(mod_s) -MSA_BINOP_DF(mod_u) MSA_BINOP_DF(dotp_s) MSA_BINOP_DF(dotp_u) MSA_BINOP_DF(srar) diff --git a/target/mips/translate.c b/target/mips/translate.c index 27eca0aa3e..50397167fc 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -28642,6 +28642,38 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) break; } break; + case OPC_MOD_S_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt); + break; + } + break; + case OPC_MOD_U_df: + switch (df) { + case DF_BYTE: + gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt); + break; + case DF_HALF: + gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt); + break; + case DF_WORD: + gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt); + break; + case DF_DOUBLE: + gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt); + break; + } + break; case OPC_SLL_df: gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt); break; @@ -28738,18 +28770,12 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_MAX_A_df: gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_MOD_S_df: - gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ILVEV_df: gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt); break; case OPC_MIN_A_df: gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt); break; - case OPC_MOD_U_df: - gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt); - break; case OPC_ILVOD_df: gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt); break; From 26f0e079a00bcf94c405f5f9b4fd53a972258a71 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:11 +0200 Subject: [PATCH 17/18] target/mips: msa: Simplify and move helper for MOVE.V Achieves clearer code and slightly better performance. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-20-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 2 +- target/mips/msa_helper.c | 31 +++++++++++++------------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index cc216f7ae5..3b1a9654e0 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -887,6 +887,7 @@ DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) +DEF_HELPER_3(msa_move_v, void, env, i32, i32) DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) DEF_HELPER_4(msa_ori_b, void, env, i32, i32, i32) @@ -977,7 +978,6 @@ DEF_HELPER_5(msa_splati_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) -DEF_HELPER_3(msa_move_v, void, env, i32, i32) DEF_HELPER_5(msa_fcaf_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_fcun_df, void, env, i32, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 04fee66042..03b198c92e 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -2022,7 +2022,19 @@ void helper_msa_mod_u_d(CPUMIPSState *env, * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Move group helpers here */ +static inline void msa_move_v(wr_t *pwd, wr_t *pws) +{ + pwd->d[0] = pws->d[0]; + pwd->d[1] = pws->d[1]; +} + +void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + + msa_move_v(pwd, pws); +} /* @@ -2079,15 +2091,6 @@ void helper_msa_mod_u_d(CPUMIPSState *env, /* TODO: insert Shift group helpers here */ -static inline void msa_move_v(wr_t *pwd, wr_t *pws) -{ - uint32_t i; - - for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { - pwd->d[i] = pws->d[i]; - } -} - #define MSA_FN_IMM8(FUNC, DEST, OPERATION) \ void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws, \ uint32_t i8) \ @@ -3874,14 +3877,6 @@ target_ulong helper_msa_cfcmsa(CPUMIPSState *env, uint32_t cs) return 0; } -void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - wr_t *pws = &(env->active_fpu.fpr[ws].wr); - - msa_move_v(pwd, pws); -} - void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd, uint32_t rs) { From 0a1bb9127ba66c093d5af395ea2630b06b929011 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Wed, 25 Sep 2019 14:46:12 +0200 Subject: [PATCH 18/18] target/mips: msa: Move helpers for .V Cosmetic reorganization. Signed-off-by: Aleksandar Markovic Reviewed-by: Aleksandar Rikalo Message-Id: <1569415572-19635-21-git-send-email-aleksandar.markovic@rt-rk.com> --- target/mips/helper.h | 9 +++-- target/mips/msa_helper.c | 81 ++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/target/mips/helper.h b/target/mips/helper.h index 3b1a9654e0..d615c83c54 100644 --- a/target/mips/helper.h +++ b/target/mips/helper.h @@ -887,6 +887,11 @@ DEF_HELPER_4(msa_mod_s_h, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_w, void, env, i32, i32, i32) DEF_HELPER_4(msa_mod_s_d, void, env, i32, i32, i32) +DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) +DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) + DEF_HELPER_3(msa_move_v, void, env, i32, i32) DEF_HELPER_4(msa_andi_b, void, env, i32, i32, i32) @@ -1021,10 +1026,6 @@ DEF_HELPER_5(msa_mulr_q_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_maddr_q_df, void, env, i32, i32, i32, i32) DEF_HELPER_5(msa_msubr_q_df, void, env, i32, i32, i32, i32) -DEF_HELPER_4(msa_and_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_or_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_nor_v, void, env, i32, i32, i32) -DEF_HELPER_4(msa_xor_v, void, env, i32, i32, i32) DEF_HELPER_4(msa_fill_df, void, env, i32, i32, i32) DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 03b198c92e..a2052baa57 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -2010,7 +2010,46 @@ void helper_msa_mod_u_d(CPUMIPSState *env, * +---------------+----------------------------------------------------------+ */ -/* TODO: insert Logic group helpers here */ + +void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = pws->d[0] & pwt->d[0]; + pwd->d[1] = pws->d[1] & pwt->d[1]; +} + +void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = ~(pws->d[0] | pwt->d[0]); + pwd->d[1] = ~(pws->d[1] | pwt->d[1]); +} + +void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = pws->d[0] | pwt->d[0]; + pwd->d[1] = pws->d[1] | pwt->d[1]; +} + +void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) +{ + wr_t *pwd = &(env->active_fpu.fpr[wd].wr); + wr_t *pws = &(env->active_fpu.fpr[ws].wr); + wr_t *pwt = &(env->active_fpu.fpr[wt].wr); + + pwd->d[0] = pws->d[0] ^ pwt->d[0]; + pwd->d[1] = pws->d[1] ^ pwt->d[1]; +} /* @@ -2160,46 +2199,6 @@ void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd, msa_move_v(pwd, pwx); } -void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - wr_t *pws = &(env->active_fpu.fpr[ws].wr); - wr_t *pwt = &(env->active_fpu.fpr[wt].wr); - - pwd->d[0] = pws->d[0] & pwt->d[0]; - pwd->d[1] = pws->d[1] & pwt->d[1]; -} - -void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - wr_t *pws = &(env->active_fpu.fpr[ws].wr); - wr_t *pwt = &(env->active_fpu.fpr[wt].wr); - - pwd->d[0] = pws->d[0] | pwt->d[0]; - pwd->d[1] = pws->d[1] | pwt->d[1]; -} - -void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - wr_t *pws = &(env->active_fpu.fpr[ws].wr); - wr_t *pwt = &(env->active_fpu.fpr[wt].wr); - - pwd->d[0] = ~(pws->d[0] | pwt->d[0]); - pwd->d[1] = ~(pws->d[1] | pwt->d[1]); -} - -void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt) -{ - wr_t *pwd = &(env->active_fpu.fpr[wd].wr); - wr_t *pws = &(env->active_fpu.fpr[ws].wr); - wr_t *pwt = &(env->active_fpu.fpr[wt].wr); - - pwd->d[0] = pws->d[0] ^ pwt->d[0]; - pwd->d[1] = pws->d[1] ^ pwt->d[1]; -} - static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2) { return arg1 + arg2;