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,