@samitouri / QOSamiQemu / commits / 35db7bdb3d

target/arm: Implement FMOP4 (non-widening) for float16

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

Richard Henderson committed Jul 2, 2026 at 13:43 UTC 35db7bdb3d276e7b224314cd254db110a4d422b4
5 files changed +62
target/arm/cpu-features.h
+5
@@ -1807,6 +1807,11 @@ isar_feature_aa64_sme_f16f16_or_f8f16(const ARMISARegisters *id)
1807 return isar_feature_aa64_sme_f16f16(id) || isar_feature_aa64_sme_f8f16(id);
1808 }
1809
1810 +static inline bool isar_feature_aa64_sme_mop4_f16f16(const ARMISARegisters *id)
1811 +{
1812 + return isar_feature_aa64_sme_mop4(id) && isar_feature_aa64_sme_f16f16(id);
1813 +}
1814 +
1815 /*
1816 * Feature tests for "does this exist in either 32-bit or 64-bit?"
1817 */
target/arm/tcg/helper-sme-defs.h
+4
@@ -356,6 +356,10 @@ DEF_HELPER_FLAGS_5(sme2_sel_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
356 DEF_HELPER_FLAGS_5(sme2_sel_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
357 DEF_HELPER_FLAGS_5(sme2_sel_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
358
359 +DEF_HELPER_FLAGS_5(sme_fmop4a_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
360 +DEF_HELPER_FLAGS_5(sme_fmop4s_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
361 +DEF_HELPER_FLAGS_5(sme_ah_fmop4s_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
362 +
363 DEF_HELPER_FLAGS_5(sme_fmop4a_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
364 DEF_HELPER_FLAGS_5(sme_fmop4s_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
365 DEF_HELPER_FLAGS_5(sme_ah_fmop4s_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
target/arm/tcg/sme.decode
+3
@@ -1094,7 +1094,10 @@ LUTI4_s_4b 1100 0000 1001 101 1 00 00 00 ....0 zd:5 \
1094 %mop4_zm 17:3 !function=times_2_plus_16
1095 %mop4_zn 6:3 !function=times_2
1096
1097 +@mop4_o1 .... .... ... m:1 .... .... .. n:1 ... . s:1 ... zad:1 \
1098 + &mop4 zm=%mop4_zm zn=%mop4_zn
1099 @mop4_o2 .... .... ... m:1 .... .... .. n:1 ... . s:1 .. zad:2 \
1100 &mop4 zm=%mop4_zm zn=%mop4_zn
1101
1102 +FMOP4_hh 1000 0001 000. ...0 0000 00.. ..0. 100. @mop4_o1
1103 FMOP4_ss 1000 0000 000. ...0 0000 00.. ..0. 00.. @mop4_o2
target/arm/tcg/sme_helper.c
+42
@@ -2636,6 +2636,48 @@ void sme_mop4(void *vza, void *vzn, void *vzm, void *fn_opaque,
2636 }
2637 }
2638
2639 +static void inner_fmop4a_hh(void *vd, void *vn, void *vm, void *vinfo)
2640 +{
2641 + float16 *d = vd, *n = vn, *m = vm;
2642 + float_status *fpst = vinfo;
2643 +
2644 + *d = float16_muladd(*n, *m, *d, 0, fpst);
2645 +}
2646 +
2647 +void HELPER(sme_fmop4a_hh)(void *vza, void *vzn, void *vzm,
2648 + float_status *fpst, uint32_t desc)
2649 +{
2650 + sme_mop4(vza, vzn, vzm, fpst, desc, sizeof(float16), inner_fmop4a_hh);
2651 +}
2652 +
2653 +static void inner_fmop4s_hh(void *vd, void *vn, void *vm, void *vinfo)
2654 +{
2655 + float16 *d = vd, *n = vn, *m = vm;
2656 + float_status *fpst = vinfo;
2657 +
2658 + *d = float16_muladd(float16_chs(*n), *m, *d, 0, fpst);
2659 +}
2660 +
2661 +void HELPER(sme_fmop4s_hh)(void *vza, void *vzn, void *vzm,
2662 + float_status *fpst, uint32_t desc)
2663 +{
2664 + sme_mop4(vza, vzn, vzm, fpst, desc, sizeof(float16), inner_fmop4s_hh);
2665 +}
2666 +
2667 +static void inner_ah_fmop4s_hh(void *vd, void *vn, void *vm, void *vinfo)
2668 +{
2669 + float16 *d = vd, *n = vn, *m = vm;
2670 + float_status *fpst = vinfo;
2671 +
2672 + *d = float16_muladd(*n, *m, *d, float_muladd_negate_product, fpst);
2673 +}
2674 +
2675 +void HELPER(sme_ah_fmop4s_hh)(void *vza, void *vzn, void *vzm,
2676 + float_status *fpst, uint32_t desc)
2677 +{
2678 + sme_mop4(vza, vzn, vzm, fpst, desc, sizeof(float16), inner_ah_fmop4s_hh);
2679 +}
2680 +
2681 static void inner_fmop4a_ss(void *vd, void *vn, void *vm, void *vinfo)
2682 {
2683 float32 *d = vd, *n = vn, *m = vm;
target/arm/tcg/translate-sme.c
+8
@@ -2025,6 +2025,14 @@ static bool do_mop4_fp(DisasContext *s, arg_mop4 *a, MemOp esz,
2025 return true;
2026 }
2027
2028 +static gen_helper_gvec_3_ptr * const fmop4_hh[3] = {
2029 + gen_helper_sme_fmop4a_hh,
2030 + gen_helper_sme_fmop4s_hh,
2031 + gen_helper_sme_ah_fmop4s_hh
2032 +};
2033 +TRANS_FEAT(FMOP4_hh, aa64_sme_mop4_f16f16,
2034 + do_mop4_fp, a, MO_16, FPST_ZA_F16, fmop4_hh)
2035 +
2036 static gen_helper_gvec_3_ptr * const fmop4_ss[3] = {
2037 gen_helper_sme_fmop4a_ss,
2038 gen_helper_sme_fmop4s_ss,