@samitouri / QOSamiQemu / commits / 1c7b4f9db3

target/arm: Implement FTMOPA (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: 20260713230244.70174-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Richard Henderson committed Aug 11, 2026 at 20:14 UTC 1c7b4f9db3ed05a09431e3e1363b4af47c28df2b
7 files changed +67
target/arm/cpu-features.h
+5
@@ -1857,6 +1857,11 @@ static inline bool isar_feature_aa64_sme_tmop_f8f16(const ARMISARegisters *id)
1857 return isar_feature_aa64_sme_tmop(id) && isar_feature_aa64_sme_f8f16(id);
1858 }
1859
1860 +static inline bool isar_feature_aa64_sme_tmop_f8f32(const ARMISARegisters *id)
1861 +{
1862 + return isar_feature_aa64_sme_tmop(id) && isar_feature_aa64_sme_f8f32(id);
1863 +}
1864 +
1865 /*
1866 * Feature tests for "does this exist in either 32-bit or 64-bit?"
1867 */
target/arm/tcg/fp8_helper.c
+7
@@ -1048,3 +1048,10 @@ void HELPER(sme_ftmopa_hb)(void *vza, void *vzn, void *vzm, void *vzk,
1048 }
1049 }
1050 }
1051 +
1052 +void HELPER(sme_ftmopa_sb)(void *vza, void *vzn, void *vzm, void *vzk,
1053 + CPUArchState *env, uint32_t desc)
1054 +{
1055 + FP8MulContext ctx = fp8_mul_start(env, 0xf);
1056 + sme_tmop_4way_sb(vza, vzn, vzm, vzk, &ctx, desc, inner_fmop4a_sb);
1057 +}
target/arm/tcg/helper-fp8-defs.h
+1
@@ -49,3 +49,4 @@ DEF_HELPER_FLAGS_5(sme_fmop4a_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32
49 DEF_HELPER_FLAGS_5(sme_fmop4a_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
50
51 DEF_HELPER_FLAGS_6(sme_ftmopa_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, env, i32)
52 +DEF_HELPER_FLAGS_6(sme_ftmopa_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, env, i32)
target/arm/tcg/sme.decode
+1
@@ -1150,3 +1150,4 @@ BFTMOPA_sh 1000 0001 010 ..... 000 ... .... .. 00 .. @tmop_o2
1150 FTMOPA_sh 1000 0001 011 ..... 000 ... .... .. 00 .. @tmop_o2
1151
1152 FTMOPA_hb 1000 0000 011 ..... 000 ... .... .. 100 . @tmop_o1
1153 +FTMOPA_sb 1000 0000 011 ..... 000 ... .... .. 00 .. @tmop_o2
target/arm/tcg/sme_helper.c
+44
@@ -2723,6 +2723,50 @@ static void sme_tmop_2way_sh(uint32_t *za, uint16_t *zn0, uint32_t *zm,
2723 }
2724 }
2725
2726 +void sme_tmop_4way_sb(uint32_t *za, uint8_t *zn0, uint32_t *zm,
2727 + uint64_t *zk, void *fn_opaque, uint32_t desc,
2728 + void (*fn)(void *, void *, void *, void *))
2729 +{
2730 + intptr_t oprsz = simd_maxsz(desc);
2731 + intptr_t dim = oprsz >> MO_32;
2732 + intptr_t index = simd_data(desc);
2733 + intptr_t ctrl_base = (index * oprsz) >> 1;
2734 + uint8_t *zn1 = zn0 + sizeof(ARMVectorReg);
2735 +
2736 + for (intptr_t row = 0; row < dim; row++) {
2737 + uint32_t *za_row = za + tile_vslice_offset(row);
2738 +
2739 + for (intptr_t col = 0; col < dim; col++) {
2740 + uint32_t *e2 = zm + H4(col);
2741 + uint32_t *e3 = za_row + H4(col);
2742 + uint16_t e1l = 0, e1h = 0;
2743 + uint32_t e1;
2744 +
2745 + /*
2746 + * Eight control bits select two elements from each row.
2747 + * The elements may be non-contiguous, so assemble them
2748 + * locally into e1.
2749 + * Pseudo-code has a triple loop running forward, with a
2750 + * test for (i < 2) to limit construction to 2 elements.
2751 + * Easier to run a single loop backward, shifting extra
2752 + * elements off the top.
2753 + */
2754 + uint64_t this_ctrl = extractn(zk, ctrl_base + col * 8, 8);
2755 + for (int e = 3; e >= 0; e--) {
2756 + if (this_ctrl & (0x01 << e)) {
2757 + e1l = (e1l << 8) | zn0[H1(4 * row + e)];
2758 + }
2759 + if (this_ctrl & (0x10 << e)) {
2760 + e1h = (e1h << 8) | zn1[H1(4 * row + e)];
2761 + }
2762 + }
2763 + e1 = (e1h << 16) | e1l;
2764 +
2765 + fn(e3, &e1, e2, fn_opaque);
2766 + }
2767 + }
2768 +}
2769 +
2770 static void inner_fmop4a_hh(void *vd, void *vn, void *vm, void *vinfo)
2771 {
2772 float16 *d = vd, *n = vn, *m = vm;
target/arm/tcg/translate-sme.c
+2
@@ -2179,3 +2179,5 @@ static bool do_tmop_fp8(DisasContext *s, arg_tmop *a, MemOp esz,
2179
2180 TRANS_FEAT(FTMOPA_hb, aa64_sme_tmop_f8f16, do_tmop_fp8,
2181 a, MO_16, gen_helper_sme_ftmopa_hb)
2182 +TRANS_FEAT(FTMOPA_sb, aa64_sme_tmop_f8f32, do_tmop_fp8,
2183 + a, MO_32, gen_helper_sme_ftmopa_sb)
target/arm/tcg/vec_internal.h
+7
@@ -555,4 +555,11 @@ void sme_mop4(void *vza, void *vzn, void *vzm, void *fn_opaque,
555 uint32_t desc, size_t esize,
556 void (*fn)(void *, void *, void *, void *));
557
558 +/*
559 + * Perform SME sparse outer product, 4-way, 8 to 32-bit.
560 + */
561 +void sme_tmop_4way_sb(uint32_t *za, uint8_t *zn0, uint32_t *zm,
562 + uint64_t *zk, void *fn_opaque, uint32_t desc,
563 + void (*fn)(void *, void *, void *, void *));
564 +
565 #endif /* TARGET_ARM_VEC_INTERNAL_H */