@samitouri / QOSamiQemu / commits / cfe1e6503a

target/arm: Implement BFTMOPA (widening)

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

Richard Henderson committed Aug 11, 2026 at 20:14 UTC cfe1e6503a0b828b7237d5c16c3b7f59f5bd7449
4 files changed +61
target/arm/tcg/helper-sme-defs.h
+2
@@ -408,3 +408,5 @@ DEF_HELPER_FLAGS_4(sme_usmop4s_dh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
408 DEF_HELPER_FLAGS_6(sme_bftmopa_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, fpst, i32)
409 DEF_HELPER_FLAGS_6(sme_ftmopa_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, fpst, i32)
410 DEF_HELPER_FLAGS_6(sme_ftmopa_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, fpst, i32)
411 +
412 +DEF_HELPER_FLAGS_6(sme_bftmopa_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, env, i32)
target/arm/tcg/sme.decode
+2
@@ -1145,3 +1145,5 @@ USMOP4_dh 1010 0001 110. ...0 0000 00.. ..0. 1... @mop4_o3
1145 BFTMOPA_hh 1000 0001 011 ..... 000 ... .... .. 100 . @tmop_o1
1146 FTMOPA_hh 1000 0001 010 ..... 000 ... .... .. 100 . @tmop_o1
1147 FTMOPA_ss 1000 0000 010 ..... 000 ... .... .. 00 .. @tmop_o2
1148 +
1149 +BFTMOPA_sh 1000 0001 010 ..... 000 ... .... .. 00 .. @tmop_o2
target/arm/tcg/sme_helper.c
+54
@@ -2679,6 +2679,50 @@ static void sme_tmop(void *vza, void *vzn, void *vzm, uint64_t *zk,
2679 }
2680 }
2681
2682 +/*
2683 + * Sparse outer product, widening 2-way, 16 to 32-bit.
2684 + */
2685 +static void sme_tmop_2way_sh(uint32_t *za, uint16_t *zn0, uint32_t *zm,
2686 + uint64_t *zk, void *fn_opaque, uint32_t desc,
2687 + void (*fn)(void *, void *, void *, void *))
2688 +{
2689 + intptr_t oprsz = simd_maxsz(desc);
2690 + intptr_t dim = oprsz >> MO_32;
2691 + intptr_t index = simd_data(desc);
2692 + intptr_t ctrl_base = (index * oprsz) >> 1;
2693 + uint16_t *zn1 = zn0 + sizeof(ARMVectorReg) / 2;
2694 +
2695 + for (intptr_t row = 0; row < dim; row++) {
2696 + uint32_t *za_row = za + tile_vslice_offset(row);
2697 +
2698 + for (intptr_t col = 0; col < dim; col++) {
2699 + uint32_t *e2 = zm + H4(col);
2700 + uint32_t *e3 = za_row + H4(col);
2701 + uint32_t e1 = 0;
2702 +
2703 + /*
2704 + * Four control bits select two elements. The two elements
2705 + * may be non-contiguous, so assemble them locally into e1.
2706 + * Pseudo-code has a double loop running forward, with a
2707 + * test for (i < 2) to limit construction to 2 elements.
2708 + * Easier to run a single loop backward, shifting extra
2709 + * elements off the top of our uint32_t.
2710 + */
2711 + uint64_t this_ctrl = extractn(zk, ctrl_base + col * 4, 4);
2712 + for (int i = 3; i >= 0; i--) {
2713 + if (this_ctrl & (1 << i)) {
2714 + bool e = i & 1;
2715 + bool r = i & 2;
2716 + uint16_t *p = (r ? zn1 : zn0) + H2(2 * row + e);
2717 + e1 = (e1 << 16) | *p;
2718 + }
2719 + }
2720 +
2721 + fn(e3, &e1, e2, fn_opaque);
2722 + }
2723 + }
2724 +}
2725 +
2726 static void inner_fmop4a_hh(void *vd, void *vn, void *vm, void *vinfo)
2727 {
2728 float16 *d = vd, *n = vn, *m = vm;
@@ -2893,6 +2937,16 @@ void HELPER(sme_bfmop4a_sh)(void *vza, void *vzn, void *vzm,
2937 : inner_bfmop4a_sh);
2938 }
2939
2940 +void HELPER(sme_bftmopa_sh)(void *vza, void *vzn, void *vzm, void *vzk,
2941 + CPUArchState *env, uint32_t desc)
2942 +{
2943 + float_status fpst;
2944 +
2945 + sme_tmop_2way_sh(vza, vzn, vzm, vzk, &fpst, desc,
2946 + is_ebf(env, &fpst) ? inner_ebf_bfmop4a_sh
2947 + : inner_bfmop4a_sh);
2948 +}
2949 +
2950 static void inner_bfmop4s_sh(void *vd, void *vn, void *vm, void *vinfo)
2951 {
2952 float32 *d = vd;
target/arm/tcg/translate-sme.c
+3
@@ -2162,3 +2162,6 @@ TRANS_FEAT(FTMOPA_hh, aa64_sme_tmop_f16f16, do_tmop_fp,
2162 a, MO_16, FPST_ZA_F16, gen_helper_sme_ftmopa_hh)
2163 TRANS_FEAT(FTMOPA_ss, aa64_sme_tmop, do_tmop_fp,
2164 a, MO_32, FPST_ZA, gen_helper_sme_ftmopa_ss)
2165 +
2166 +TRANS_FEAT(BFTMOPA_sh, aa64_sme_tmop, do_tmop_fp,
2167 + a, MO_32, FPST_ENV, gen_helper_sme_bftmopa_sh)