target/arm: Implement F1CVT, F1CVTL, F2CVT, F2CVTL for SME
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260609192110.752384-14-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Richard Henderson committed
Jun 9, 2026 at 12:20 UTC
cfbf701e7ab148f7de0eed9f93acf74b916e0ff2
4 files changed
+59
target/arm/tcg/fp8_helper.c
+47
@@ -211,6 +211,33 @@ void HELPER(sme2_bfcvt_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
211
fp8_cvt_finish(env, &ctx);
212
}
213
214
+void HELPER(sme2_fcvt_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
215
+{
216
+ FP8Context ctx = fp8_src_start(env, desc, 0xf);
217
+ fp8_input_fn *input_fmt = fp8_input_fmt[ctx.f8fmt];
218
+ uint8_t *n = vn;
219
+ uint16_t *d0 = vd;
220
+ uint16_t *d1 = vd + sizeof(ARMVectorReg);
221
+ size_t oprsz = simd_oprsz(desc);
222
+ size_t nelem = oprsz / 2;
223
+ ARMVectorReg scratch;
224
+
225
+ if (vectors_overlap(vd, 2, vn, 1)) {
226
+ n = memcpy(&scratch, vn, oprsz);
227
+ }
228
+
229
+ for (size_t i = 0; i < nelem; ++i) {
230
+ d0[H2(i)] = fcvt_fp8_to_f16(n[H1(i)], input_fmt,
231
+ ctx.scale, &ctx.stat);
232
+ }
233
+ for (size_t i = 0; i < nelem; ++i) {
234
+ d1[H2(i)] = fcvt_fp8_to_f16(n[H1(i + nelem)], input_fmt,
235
+ ctx.scale, &ctx.stat);
236
+ }
237
+
238
+ fp8_cvt_finish(env, &ctx);
239
+}
240
+
241
void HELPER(sme2_bfcvtl_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
242
{
243
FP8Context ctx = fp8_src_start(env, desc, 0x3f);
@@ -230,3 +257,23 @@ void HELPER(sme2_bfcvtl_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
257
258
fp8_cvt_finish(env, &ctx);
259
}
260
+
261
+void HELPER(sme2_fcvtl_hb)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
262
+{
263
+ FP8Context ctx = fp8_src_start(env, desc, 0xf);
264
+ fp8_input_fn *input_fmt = fp8_input_fmt[ctx.f8fmt];
265
+ uint8_t *n = vn;
266
+ uint16_t *d0 = vd;
267
+ uint16_t *d1 = vd + sizeof(ARMVectorReg);
268
+ size_t oprsz = simd_oprsz(desc);
269
+ size_t nelem = oprsz / 2;
270
+
271
+ for (size_t i = 0; i < nelem; ++i) {
272
+ uint8_t e0 = n[H1(2 * i + 0)];
273
+ uint8_t e1 = n[H1(2 * i + 1)];
274
+ d0[H2(i)] = fcvt_fp8_to_f16(e0, input_fmt, ctx.scale, &ctx.stat);
275
+ d1[H2(i)] = fcvt_fp8_to_f16(e1, input_fmt, ctx.scale, &ctx.stat);
276
+ }
277
+
278
+ fp8_cvt_finish(env, &ctx);
279
+}
target/arm/tcg/helper-fp8-defs.h
+2
@@ -10,3 +10,5 @@ DEF_HELPER_FLAGS_4(sme2_bfcvtl_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
10
11
DEF_HELPER_FLAGS_4(advsimd_fcvtl_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
12
DEF_HELPER_FLAGS_4(sve2_fcvt_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
13
+DEF_HELPER_FLAGS_4(sme2_fcvt_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
14
+DEF_HELPER_FLAGS_4(sme2_fcvtl_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
+F1CVT 11000001 001 00110 111000 ..... ....0 @zz_2x1
857
+F2CVT 11000001 101 00110 111000 ..... ....0 @zz_2x1
858
+F1CVTL 11000001 001 00110 111000 ..... ....1 @zz_2x1
859
+F2CVTL 11000001 101 00110 111000 ..... ....1 @zz_2x1
860
+
861
BF1CVT 11000001 011 00110 111000 ..... ....0 @zz_2x1
862
BF2CVT 11000001 111 00110 111000 ..... ....0 @zz_2x1
863
BF1CVTL 11000001 011 00110 111000 ..... ....1 @zz_2x1
target/arm/tcg/translate-sme.c
+5
@@ -1546,6 +1546,11 @@ static bool do_f8cvt(DisasContext *s, arg_zz_n *a,
1546
return true;
1547
}
1548
1549
+TRANS_FEAT(F1CVT, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_fcvt_hb, 0)
1550
+TRANS_FEAT(F2CVT, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_fcvt_hb, 1)
1551
+TRANS_FEAT(F1CVTL, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_fcvtl_hb, 0)
1552
+TRANS_FEAT(F2CVTL, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_fcvtl_hb, 1)
1553
+
1554
TRANS_FEAT(BF1CVT, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvt_hb, 0)
1555
TRANS_FEAT(BF2CVT, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvt_hb, 1)
1556
TRANS_FEAT(BF1CVTL, aa64_sme2_f8cvt, do_f8cvt, a, gen_helper_sme2_bfcvtl_hb, 0)