@samitouri / QOSamiQemu / commits / aa3a898dce

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

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

Richard Henderson committed Jul 2, 2026 at 13:43 UTC aa3a898dce7947ef938c1953d9c6186ad7d6abe9
5 files changed +46
target/arm/cpu-features.h
+5
@@ -1822,6 +1822,11 @@ static inline bool isar_feature_aa64_sme_mop4_f64f64(const ARMISARegisters *id)
1822 return isar_feature_aa64_sme_mop4(id) && isar_feature_aa64_sme_f64f64(id);
1823 }
1824
1825 +static inline bool isar_feature_aa64_sme_mop4_f8f32(const ARMISARegisters *id)
1826 +{
1827 + return isar_feature_aa64_sme_mop4(id) && isar_feature_aa64_sme_f8f32(id);
1828 +}
1829 +
1830 /*
1831 * Feature tests for "does this exist in either 32-bit or 64-bit?"
1832 */
target/arm/tcg/fp8_helper.c
+16
@@ -973,3 +973,19 @@ void HELPER(sme_fvdot_idx_hb)(void *vd, void *vn, void *vm,
973 } while (++i & 7);
974 } while (i < elements);
975 }
976 +
977 +static void inner_fmop4a_sb(void *vd, void *vn, void *vm, void *vinfo)
978 +{
979 + float32 *d = vd;
980 + uint32_t *n = vn, *m = vm;
981 + FP8MulContext *ctx = vinfo;
982 +
983 + *d = f8dotadd_s(*n, *m, 4, *d, ctx);
984 +}
985 +
986 +void HELPER(sme_fmop4a_sb)(void *vza, void *vzn, void *vzm,
987 + CPUArchState *env, uint32_t desc)
988 +{
989 + FP8MulContext ctx = fp8_mul_start(env, -1);
990 + sme_mop4(vza, vzn, vzm, &ctx, desc, sizeof(float32), inner_fmop4a_sb);
991 +}
target/arm/tcg/helper-fp8-defs.h
+2
@@ -44,3 +44,5 @@ DEF_HELPER_FLAGS_7(sme_fmopa_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr,
44
45 DEF_HELPER_FLAGS_5(sme_fvdot_idx_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
46 DEF_HELPER_FLAGS_5(sme_fvdot_idx_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
47 +
48 +DEF_HELPER_FLAGS_5(sme_fmop4a_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
target/arm/tcg/sme.decode
+5
@@ -1101,6 +1101,9 @@ LUTI4_s_4b 1100 0000 1001 101 1 00 00 00 ....0 zd:5 \
1101 @mop4_o3 .... .... ... m:1 .... .... .. n:1 ... . s:1 . zad:3 \
1102 &mop4 zm=%mop4_zm zn=%mop4_zn
1103
1104 +@mop4_o2_s0 .... .... ... m:1 .... .... .. n:1 ... . ... zad:2 \
1105 + &mop4 zm=%mop4_zm zn=%mop4_zn s=0
1106 +
1107 BFMOP4_hh 1000 0001 001. ...0 0000 00.. ..0. 100. @mop4_o1
1108 FMOP4_hh 1000 0001 000. ...0 0000 00.. ..0. 100. @mop4_o1
1109 FMOP4_ss 1000 0000 000. ...0 0000 00.. ..0. 00.. @mop4_o2
@@ -1108,3 +1111,5 @@ FMOP4_dd 1000 0000 110. ...0 0000 00.. ..0. 1... @mop4_o3
1111
1112 BFMOP4_sh 1000 0001 000. ...0 0000 00.. ..0. 00.. @mop4_o2
1113 FMOP4_sh 1000 0001 001. ...0 0000 00.. ..0. 00.. @mop4_o2
1114 +
1115 +FMOP4A_sb 1000 0000 001. ...0 0000 00.. ..00 00.. @mop4_o2_s0
target/arm/tcg/translate-sme.c
+18
@@ -2072,3 +2072,21 @@ static gen_helper_gvec_3_ptr * const fmop4_sh[3] = {
2072 gen_helper_sme_ah_fmop4s_sh
2073 };
2074 TRANS_FEAT(FMOP4_sh, aa64_sme_mop4, do_mop4_fp, a, MO_32, FPST_ENV, fmop4_sh)
2075 +
2076 +static bool do_mop4_fp8(DisasContext *s, arg_mop4 *a, MemOp esz,
2077 + gen_helper_gvec_3_ptr *fn)
2078 +{
2079 + if (fpmr_access_check(s) && sme_smza_enabled_check(s)) {
2080 + int svl = streaming_vec_reg_size(s);
2081 + uint32_t desc = simd_desc(svl, svl, (a->m << 1) | a->n);
2082 + TCGv_ptr za = get_tile(s, esz, a->zad);
2083 + TCGv_ptr zn = vec_full_reg_ptr(s, a->zn);
2084 + TCGv_ptr zm = vec_full_reg_ptr(s, a->zm);
2085 +
2086 + fn(za, zn, zm, tcg_env, tcg_constant_i32(desc));
2087 + }
2088 + return true;
2089 +}
2090 +
2091 +TRANS_FEAT(FMOP4A_sb, aa64_sme_mop4_f8f32,
2092 + do_mop4_fp8, a, MO_32, gen_helper_sme_fmop4a_sb)