@samitouri / QOSamiQemu / commits / 54bd1aa21a

target/arm: Implement BFMOP4 (widening)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260702204314.79224-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Richard Henderson committed Jul 2, 2026 at 13:43 UTC 54bd1aa21a705487fec8c01bff1ec8dcc5a1082b
4 files changed +103 -3
target/arm/tcg/helper-sme-defs.h
+4
@@ -371,3 +371,7 @@ DEF_HELPER_FLAGS_5(sme_ah_fmop4s_dd, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst,
371 DEF_HELPER_FLAGS_5(sme_bfmop4a_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
372 DEF_HELPER_FLAGS_5(sme_bfmop4s_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
373 DEF_HELPER_FLAGS_5(sme_ah_bfmop4s_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
374 +
375 +DEF_HELPER_FLAGS_5(sme_bfmop4a_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
376 +DEF_HELPER_FLAGS_5(sme_bfmop4s_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
377 +DEF_HELPER_FLAGS_5(sme_ah_bfmop4s_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
target/arm/tcg/sme.decode
+2
@@ -1105,3 +1105,5 @@ BFMOP4_hh 1000 0001 001. ...0 0000 00.. ..0. 100. @mop4_o1
1105 FMOP4_hh 1000 0001 000. ...0 0000 00.. ..0. 100. @mop4_o1
1106 FMOP4_ss 1000 0000 000. ...0 0000 00.. ..0. 00.. @mop4_o2
1107 FMOP4_dd 1000 0000 110. ...0 0000 00.. ..0. 1... @mop4_o3
1108 +
1109 +BFMOP4_sh 1000 0001 000. ...0 0000 00.. ..0. 00.. @mop4_o2
target/arm/tcg/sme_helper.c
+84
@@ -2803,3 +2803,87 @@ void HELPER(sme_ah_bfmop4s_hh)(void *vza, void *vzn, void *vzm,
2803 {
2804 sme_mop4(vza, vzn, vzm, fpst, desc, sizeof(bfloat16), inner_ah_bfmop4s_hh);
2805 }
2806 +
2807 +static void inner_bfmop4a_sh(void *vd, void *vn, void *vm, void *vinfo)
2808 +{
2809 + float32 *d = vd;
2810 + uint32_t *n = vn, *m = vm;
2811 + float_status *fpst = vinfo;
2812 +
2813 + *d = bfdotadd(*d, *n, *m, fpst);
2814 +}
2815 +
2816 +static void inner_ebf_bfmop4a_sh(void *vd, void *vn, void *vm, void *vinfo)
2817 +{
2818 + float32 *d = vd;
2819 + uint32_t *n = vn, *m = vm;
2820 + float_status *fpst = vinfo;
2821 +
2822 + *d = bfdotadd_ebf(*d, *n, *m, fpst);
2823 +}
2824 +
2825 +void HELPER(sme_bfmop4a_sh)(void *vza, void *vzn, void *vzm,
2826 + CPUArchState *env, uint32_t desc)
2827 +{
2828 + float_status fpst;
2829 +
2830 + sme_mop4(vza, vzn, vzm, &fpst, desc, sizeof(float32),
2831 + is_ebf(env, &fpst) ? inner_ebf_bfmop4a_sh
2832 + : inner_bfmop4a_sh);
2833 +}
2834 +
2835 +static void inner_bfmop4s_sh(void *vd, void *vn, void *vm, void *vinfo)
2836 +{
2837 + float32 *d = vd;
2838 + uint32_t *n = vn, *m = vm;
2839 + float_status *fpst = vinfo;
2840 +
2841 + *d = bfdotadd(*d, *n ^ 0x80008000u, *m, fpst);
2842 +}
2843 +
2844 +static void inner_ebf_bfmop4s_sh(void *vd, void *vn, void *vm, void *vinfo)
2845 +{
2846 + float32 *d = vd;
2847 + uint32_t *n = vn, *m = vm;
2848 + float_status *fpst = vinfo;
2849 +
2850 + *d = bfdotadd_ebf(*d, *n ^ 0x80008000u, *m, fpst);
2851 +}
2852 +
2853 +void HELPER(sme_bfmop4s_sh)(void *vza, void *vzn, void *vzm,
2854 + CPUArchState *env, uint32_t desc)
2855 +{
2856 + float_status fpst;
2857 +
2858 + sme_mop4(vza, vzn, vzm, &fpst, desc, sizeof(float32),
2859 + is_ebf(env, &fpst) ? inner_ebf_bfmop4s_sh
2860 + : inner_bfmop4s_sh);
2861 +}
2862 +
2863 +static void inner_ah_bfmop4s_sh(void *vd, void *vn, void *vm, void *vinfo)
2864 +{
2865 + float32 *d = vd;
2866 + uint32_t *n = vn, *m = vm;
2867 + float_status *fpst = vinfo;
2868 +
2869 + *d = bfdotadd(*d, bf16mop_ah_neg_adj_pair(*n, -1), *m, fpst);
2870 +}
2871 +
2872 +static void inner_ebf_ah_bfmop4s_sh(void *vd, void *vn, void *vm, void *vinfo)
2873 +{
2874 + float32 *d = vd;
2875 + uint32_t *n = vn, *m = vm;
2876 + float_status *fpst = vinfo;
2877 +
2878 + *d = bfdotadd_ebf(*d, bf16mop_ah_neg_adj_pair(*n, -1), *m, fpst);
2879 +}
2880 +
2881 +void HELPER(sme_ah_bfmop4s_sh)(void *vza, void *vzn, void *vzm,
2882 + CPUArchState *env, uint32_t desc)
2883 +{
2884 + float_status fpst;
2885 +
2886 + sme_mop4(vza, vzn, vzm, &fpst, desc, sizeof(float32),
2887 + is_ebf(env, &fpst) ? inner_ebf_ah_bfmop4s_sh
2888 + : inner_ah_bfmop4s_sh);
2889 +}
target/arm/tcg/translate-sme.c
+13 -3
@@ -2004,8 +2004,7 @@ TRANS_FEAT(LUTI4_s_4b, aa64_sme2p1_lutv2, do_lut_s4, a,
2004 gen_helper_sme2_luti4_4b)
2005
2006 static bool do_mop4_fp(DisasContext *s, arg_mop4 *a, MemOp esz,
2007 - ARMFPStatusFlavour e_fpst,
2008 - gen_helper_gvec_3_ptr * const fns[3])
2007 + int e_fpst, gen_helper_gvec_3_ptr * const fns[3])
2008 {
2009 int svl = streaming_vec_reg_size(s);
2010 uint32_t desc = simd_desc(svl, svl, (a->m << 1) | a->n);
@@ -2019,7 +2018,11 @@ static bool do_mop4_fp(DisasContext *s, arg_mop4 *a, MemOp esz,
2018 za = get_tile(s, esz, a->zad);
2019 zn = vec_full_reg_ptr(s, a->zn);
2020 zm = vec_full_reg_ptr(s, a->zm);
2022 - fpst = fpstatus_ptr(e_fpst);
2021 + if (e_fpst >= 0) {
2022 + fpst = fpstatus_ptr(e_fpst);
2023 + } else {
2024 + fpst = tcg_env;
2025 + }
2026
2027 fns[fns_idx](za, zn, zm, fpst, tcg_constant_i32(desc));
2028 return true;
@@ -2055,3 +2058,10 @@ static gen_helper_gvec_3_ptr * const fmop4_dd[3] = {
2058 };
2059 TRANS_FEAT(FMOP4_dd, aa64_sme_mop4_f64f64,
2060 do_mop4_fp, a, MO_64, FPST_ZA, fmop4_dd)
2061 +
2062 +static gen_helper_gvec_3_ptr * const bfmop4_sh[3] = {
2063 + gen_helper_sme_bfmop4a_sh,
2064 + gen_helper_sme_bfmop4s_sh,
2065 + gen_helper_sme_ah_bfmop4s_sh
2066 +};
2067 +TRANS_FEAT(BFMOP4_sh, aa64_sme_mop4, do_mop4_fp, a, MO_32, FPST_ENV, bfmop4_sh)