@samitouri / QOSamiQemu / commits / aa0d730495

target/arm: Implement BF1CVT, BF1CVTL, BF2CVT, BF2CVTL for SME

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

Richard Henderson committed Jun 9, 2026 at 12:20 UTC aa0d730495b360cf9a1b0a5724fd9ca6768891a2
4 files changed +73
target/arm/tcg/fp8_helper.c
+47
@@ -138,3 +138,50 @@ void HELPER(sve2_bfcvt)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
138
139 fp8_cvt_finish(env, &ctx);
140 }
141 +
142 +void HELPER(sme2_bfcvt_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
143 +{
144 + FP8Context ctx = fp8_src_start(env, desc, 0x3f);
145 + fp8_input_fn *input_fmt = fp8_input_fmt[ctx.f8fmt];
146 + uint8_t *n = vn;
147 + uint16_t *d0 = vd;
148 + uint16_t *d1 = vd + sizeof(ARMVectorReg);
149 + size_t oprsz = simd_oprsz(desc);
150 + size_t nelem = oprsz / 2;
151 + ARMVectorReg scratch;
152 +
153 + if (vectors_overlap(vd, 2, vn, 1)) {
154 + n = memcpy(&scratch, vn, oprsz);
155 + }
156 +
157 + for (size_t i = 0; i < nelem; ++i) {
158 + d0[H2(i)] = fcvt_fp8_to_b16(n[H1(i)], input_fmt,
159 + ctx.scale, &ctx.stat);
160 + }
161 + for (size_t i = 0; i < nelem; ++i) {
162 + d1[H2(i)] = fcvt_fp8_to_b16(n[H1(i + nelem)], input_fmt,
163 + ctx.scale, &ctx.stat);
164 + }
165 +
166 + fp8_cvt_finish(env, &ctx);
167 +}
168 +
169 +void HELPER(sme2_bfcvtl_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
170 +{
171 + FP8Context ctx = fp8_src_start(env, desc, 0x3f);
172 + fp8_input_fn *input_fmt = fp8_input_fmt[ctx.f8fmt];
173 + uint8_t *n = vn;
174 + uint16_t *d0 = vd;
175 + uint16_t *d1 = vd + sizeof(ARMVectorReg);
176 + size_t oprsz = simd_oprsz(desc);
177 + size_t nelem = oprsz / 2;
178 +
179 + for (size_t i = 0; i < nelem; ++i) {
180 + uint8_t e0 = n[H1(2 * i + 0)];
181 + uint8_t e1 = n[H1(2 * i + 1)];
182 + d0[H2(i)] = fcvt_fp8_to_b16(e0, input_fmt, ctx.scale, &ctx.stat);
183 + d1[H2(i)] = fcvt_fp8_to_b16(e1, input_fmt, ctx.scale, &ctx.stat);
184 + }
185 +
186 + fp8_cvt_finish(env, &ctx);
187 +}
target/arm/tcg/helper-fp8-defs.h
+2
@@ -5,3 +5,5 @@
5
6 DEF_HELPER_FLAGS_4(advsimd_bfcvtl, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
7 DEF_HELPER_FLAGS_4(sve2_bfcvt, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
8 +DEF_HELPER_FLAGS_4(sme2_bfcvt_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
9 +DEF_HELPER_FLAGS_4(sme2_bfcvtl_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
target/arm/tcg/sme.decode
+5
@@ -853,6 +853,11 @@ UUNPK_4bh 11000001 011 10101 111000 ....0 ...01 @zz_4x2_n1
853 UUNPK_4hs 11000001 101 10101 111000 ....0 ...01 @zz_4x2_n1
854 UUNPK_4sd 11000001 111 10101 111000 ....0 ...01 @zz_4x2_n1
855
856 +BF1CVT 11000001 011 00110 111000 ..... ....0 @zz_2x1
857 +BF2CVT 11000001 111 00110 111000 ..... ....0 @zz_2x1
858 +BF1CVTL 11000001 011 00110 111000 ..... ....1 @zz_2x1
859 +BF2CVTL 11000001 111 00110 111000 ..... ....1 @zz_2x1
860 +
861 ZIP_4 11000001 esz:2 1 10110 111000 ...00 ... 00 \
862 &zz_e zd=%zd_ax4 zn=%zn_ax4
863 ZIP_4 11000001 001 10111 111000 ...00 ... 00 \
target/arm/tcg/translate-sme.c
+19
@@ -22,6 +22,7 @@
22 #include "helper-a64.h"
23 #include "helper-sme.h"
24 #include "helper-sve.h"
25 +#include "helper-fp8.h"
26 #include "translate.h"
27 #include "translate-a64.h"
28 #include "tcg/tcg-op.h"
@@ -1532,6 +1533,24 @@ TRANS_FEAT(UUNPK_4bh, aa64_sme2, do_zz, a, 0, gen_helper_sme2_uunpk4_bh)
1533 TRANS_FEAT(UUNPK_4hs, aa64_sme2, do_zz, a, 0, gen_helper_sme2_uunpk4_hs)
1534 TRANS_FEAT(UUNPK_4sd, aa64_sme2, do_zz, a, 0, gen_helper_sme2_uunpk4_sd)
1535
1536 +static bool do_f8cvt(DisasContext *s, arg_zz_n *a,
1537 + gen_helper_gvec_2_ptr *fn, bool issrc2)
1538 +{
1539 + if (fpmr_access_check(s) && sme_sm_enabled_check(s)) {
1540 + int svl = streaming_vec_reg_size(s);
1541 + tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->zd),
1542 + vec_full_reg_offset(s, a->zn),
1543 + tcg_env, svl, svl,
1544 + issrc2 | (FPST_ZA << 2), fn);
1545 + }
1546 + return true;
1547 +}
1548 +
1549 +TRANS_FEAT(BF1CVT, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvt_hb, 0)
1550 +TRANS_FEAT(BF2CVT, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvt_hb, 1)
1551 +TRANS_FEAT(BF1CVTL, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvtl_hb, 0)
1552 +TRANS_FEAT(BF2CVTL, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvtl_hb, 1)
1553 +
1554 static bool do_zipuzp_4(DisasContext *s, arg_zz_e *a,
1555 gen_helper_gvec_2 * const fn[5])
1556 {