diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-11-04 15:40:39 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-06-05 09:05:53 -0700 |
commit | d6ff1ccb45f9b228e20f74f6e6c801c88a2885b2 (patch) | |
tree | 1c4dd3622e5a608fd170469ff6dcecd8a1fe71fa /target/sparc | |
parent | 1d3ed3d728f81dee4ae87028a8a3e9beb4fa4a17 (diff) | |
download | qemu-d6ff1ccb45f9b228e20f74f6e6c801c88a2885b2.zip qemu-d6ff1ccb45f9b228e20f74f6e6c801c88a2885b2.tar.gz qemu-d6ff1ccb45f9b228e20f74f6e6c801c88a2885b2.tar.bz2 |
target/sparc: Implement FMEAN16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/sparc')
-rw-r--r-- | target/sparc/helper.h | 1 | ||||
-rw-r--r-- | target/sparc/insns.decode | 1 | ||||
-rw-r--r-- | target/sparc/translate.c | 30 | ||||
-rw-r--r-- | target/sparc/vis_helper.c | 21 |
4 files changed, 53 insertions, 0 deletions
diff --git a/target/sparc/helper.h b/target/sparc/helper.h index ab79954..f1b84dc 100644 --- a/target/sparc/helper.h +++ b/target/sparc/helper.h @@ -118,6 +118,7 @@ DEF_HELPER_FLAGS_2(cmask8, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmask16, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmask32, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(fchksm16, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmean16, TCG_CALL_NO_RWG_SE, i64, i64, i64) #define VIS_CMPHELPER(name) \ DEF_HELPER_FLAGS_2(f##name##16, TCG_CALL_NO_RWG_SE, \ i64, i64, i64) \ diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode index de29996..febd1a4 100644 --- a/target/sparc/insns.decode +++ b/target/sparc/insns.decode @@ -421,6 +421,7 @@ FCMPEq 10 000 cc:2 110101 ..... 0 0101 0111 ..... \ PDIST 10 ..... 110110 ..... 0 0011 1110 ..... \ &r_r_r_r rd=%dfp_rd rs1=%dfp_rd rs2=%dfp_rs1 rs3=%dfp_rs2 + FMEAN16 10 ..... 110110 ..... 0 0100 0000 ..... @d_d_d FCHKSM16 10 ..... 110110 ..... 0 0100 0100 ..... @d_d_d FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @d_d_d FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @d_r_r diff --git a/target/sparc/translate.c b/target/sparc/translate.c index db3a153..c3956f4 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -815,8 +815,37 @@ static void gen_op_fchksm16(unsigned vece, uint32_t dofs, uint32_t aofs, }; tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &op); } + +static void gen_vec_fmean16(unsigned vece, TCGv_vec dst, + TCGv_vec src1, TCGv_vec src2) +{ + TCGv_vec t = tcg_temp_new_vec_matching(dst); + + tcg_gen_or_vec(vece, t, src1, src2); + tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(dst, vece, 1)); + tcg_gen_sari_vec(vece, src1, src1, 1); + tcg_gen_sari_vec(vece, src2, src2, 1); + tcg_gen_add_vec(vece, dst, src1, src2); + tcg_gen_add_vec(vece, dst, dst, t); +} + +static void gen_op_fmean16(unsigned vece, uint32_t dofs, uint32_t aofs, + uint32_t bofs, uint32_t oprsz, uint32_t maxsz) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_add_vec, INDEX_op_sari_vec, + }; + static const GVecGen3 op = { + .fni8 = gen_helper_fmean16, + .fniv = gen_vec_fmean16, + .opt_opc = vecop_list, + .vece = MO_16, + }; + tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &op); +} #else #define gen_op_fchksm16 ({ qemu_build_not_reached(); NULL; }) +#define gen_op_fmean16 ({ qemu_build_not_reached(); NULL; }) #endif static void finishing_insn(DisasContext *dc) @@ -4844,6 +4873,7 @@ TRANS(FPADD32, VIS1, do_gvec_ddd, a, MO_32, tcg_gen_gvec_add) TRANS(FPSUB16, VIS1, do_gvec_ddd, a, MO_16, tcg_gen_gvec_sub) TRANS(FPSUB32, VIS1, do_gvec_ddd, a, MO_32, tcg_gen_gvec_sub) TRANS(FCHKSM16, VIS3, do_gvec_ddd, a, MO_16, gen_op_fchksm16) +TRANS(FMEAN16, VIS3, do_gvec_ddd, a, MO_16, gen_op_fmean16) static bool do_ddd(DisasContext *dc, arg_r_r_r *a, void (*func)(TCGv_i64, TCGv_i64, TCGv_i64)) diff --git a/target/sparc/vis_helper.c b/target/sparc/vis_helper.c index fa60737..6ef3675 100644 --- a/target/sparc/vis_helper.c +++ b/target/sparc/vis_helper.c @@ -412,3 +412,24 @@ uint64_t helper_fchksm16(uint64_t src1, uint64_t src2) return r.ll; } + +static inline int16_t do_fmean16(int16_t src1, int16_t src2) +{ + return (src1 + src2 + 1) / 2; +} + +uint64_t helper_fmean16(uint64_t src1, uint64_t src2) +{ + VIS64 r, s1, s2; + + s1.ll = src1; + s2.ll = src2; + r.ll = 0; + + r.VIS_SW64(0) = do_fmean16(s1.VIS_SW64(0), s2.VIS_SW64(0)); + r.VIS_SW64(1) = do_fmean16(s1.VIS_SW64(1), s2.VIS_SW64(1)); + r.VIS_SW64(2) = do_fmean16(s1.VIS_SW64(2), s2.VIS_SW64(2)); + r.VIS_SW64(3) = do_fmean16(s1.VIS_SW64(3), s2.VIS_SW64(3)); + + return r.ll; +} |