@samitouri / QOSamiQemu / commits / 7818f3d6e9

target/arm: Implement FMOPA (widening, 4-way fp8 to fp32)

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

Richard Henderson committed Jun 17, 2026 at 21:15 UTC 7818f3d6e90b8ce7b58ece18da004a8026d0d01a
5 files changed +63
target/arm/cpu-features.h
+5
@@ -1600,6 +1600,11 @@ static inline bool isar_feature_aa64_sme_b16b16(const ARMISARegisters *id)
1600 return FIELD_EX64_IDREG(id, ID_AA64SMFR0, B16B16);
1601 }
1602
1603 +static inline bool isar_feature_aa64_sme_f8f32(const ARMISARegisters *id)
1604 +{
1605 + return FIELD_EX64_IDREG(id, ID_AA64SMFR0, F8F32);
1606 +}
1607 +
1608 static inline bool isar_feature_aa64_sme_f16f16(const ARMISARegisters *id)
1609 {
1610 return FIELD_EX64_IDREG(id, ID_AA64SMFR0, F16F16);
target/arm/tcg/fp8_helper.c
+35
@@ -857,3 +857,38 @@ void HELPER(gvec_fmmla_hb)(void *vd, void *vn, void *vm,
857
858 clear_tail(vd, oprsz, simd_maxsz(desc));
859 }
860 +
861 +void HELPER(sme_fmopa_sb)(void *vza, void *vzn, void *vzm, void *vpn,
862 + void *vpm, CPUARMState *env, uint32_t desc)
863 +{
864 + FP8MulContext ctx = fp8_mul_start(env, -1);
865 + intptr_t oprsz = simd_maxsz(desc);
866 + uint16_t *pn = vpn, *pm = vpm;
867 +
868 + for (intptr_t row = 0; row < oprsz; ) {
869 + uint16_t prow = pn[H2(row >> 4)];
870 + do {
871 + void *vza_row = vza + tile_vslice_offset(row);
872 + uint32_t n = *(uint32_t *)(vzn + H1_4(row));
873 +
874 + n &= expand_pred_b(prow & 0xf);
875 +
876 + for (intptr_t col = 0; col < oprsz; ) {
877 + uint16_t pcol = pm[H2(col >> 4)];
878 + do {
879 + if (prow & pcol & 0xf) {
880 + uint32_t *a = vza_row + H1_4(col);
881 + uint32_t m = *(uint32_t *)(vzm + H1_4(col));
882 +
883 + m &= expand_pred_b(pcol & 0xf);
884 + *a = f8dotadd_s(n, m, 4, *a, &ctx);
885 + }
886 + col += 4;
887 + pcol >>= 4;
888 + } while (col & 15);
889 + }
890 + row += 4;
891 + prow >>= 4;
892 + } while (row & 15);
893 + }
894 +}
target/arm/tcg/helper-fp8-defs.h
+2
@@ -38,3 +38,5 @@ DEF_HELPER_FLAGS_5(gvec_fdot_idx_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env,
38
39 DEF_HELPER_FLAGS_5(gvec_fmmla_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
40 DEF_HELPER_FLAGS_5(gvec_fmmla_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
41 +
42 +DEF_HELPER_FLAGS_7(sme_fmopa_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, env, i32)
target/arm/tcg/sme.decode
+2
@@ -198,6 +198,8 @@ BFMOPA 10000001 101 ..... ... ... ..... . 100 . @op_16
198 BFMOPA_w 10000001 100 ..... ... ... ..... . 00 .. @op_32
199 FMOPA_w_h 10000001 101 ..... ... ... ..... . 00 .. @op_32
200
201 +FMOPA_sb 10000000 101 zm:5 pm:3 pn:3 zn:5 0 00 zad:2 &op sub=0
202 +
203 SMOPA_s 1010000 0 10 0 ..... ... ... ..... . 00 .. @op_32
204 SUMOPA_s 1010000 0 10 1 ..... ... ... ..... . 00 .. @op_32
205 USMOPA_s 1010000 1 10 0 ..... ... ... ..... . 00 .. @op_32
target/arm/tcg/translate-sme.c
+19
@@ -616,6 +616,25 @@ TRANS_FEAT(BFMOPA_w, aa64_sme, do_outprod_env, a, MO_32,
616 : !s->fpcr_ah ? gen_helper_sme_bfmops_w
617 : gen_helper_sme_ah_bfmops_w)
618
619 +static bool trans_FMOPA_sb(DisasContext *s, arg_op *a)
620 +{
621 + if (!dc_isar_feature(aa64_sme_f8f32, s)) {
622 + return false;
623 + }
624 + if (fpmr_access_check(s) && sme_smza_enabled_check(s)) {
625 + int svl = streaming_vec_reg_size(s);
626 + uint32_t desc = simd_desc(svl, svl, 0);
627 +
628 + gen_helper_sme_fmopa_sb(get_tile(s, MO_32, a->zad),
629 + vec_full_reg_ptr(s, a->zn),
630 + vec_full_reg_ptr(s, a->zm),
631 + pred_full_reg_ptr(s, a->pn),
632 + pred_full_reg_ptr(s, a->pm),
633 + tcg_env, tcg_constant_i32(desc));
634 + }
635 + return true;
636 +}
637 +
638 TRANS_FEAT(SMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_smopa_s)
639 TRANS_FEAT(UMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_umopa_s)
640 TRANS_FEAT(SUMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_sumopa_s)