target/arm: Implement FCVTN (16- to 8-bit fp) for SVE
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260609192110.752384-18-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Richard Henderson committed
Jun 9, 2026 at 12:20 UTC
5c5352e3b8cf146492c342b7355f6fd88898aa5d
4 files changed
+27
target/arm/tcg/fp8_helper.c
+23
@@ -414,6 +414,29 @@ void HELPER(gvec_fcvt_bh)(void *vd, void *vn, void *vm,
414
clear_tail(vd, oprsz, simd_maxsz(desc));
415
}
416
417
+void HELPER(sve2_fcvtn_bh)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
418
+{
419
+ FP8Context ctx = fp8_dst_start(env, desc, true);
420
+ fcvt_fp8_output_fn *output_fmt = fcvt_fp8_output_fmt[ctx.f8fmt];
421
+ uint16_t *n0 = vn;
422
+ uint16_t *n1 = vn + sizeof(ARMVectorReg);
423
+ uint8_t *d = vd;
424
+ bool osc = FIELD_EX64(env->vfp.fpmr, FPMR, OSC);
425
+ size_t oprsz = simd_oprsz(desc);
426
+ size_t nelem = oprsz / 2;
427
+
428
+ for (size_t i = 0; i < nelem; ++i) {
429
+ float16 e0 = n0[H2(i)];
430
+ float16 e1 = n1[H2(i)];
431
+ d[H1(2 * i + 0)] = fcvt_f16_to_fp8(e0, output_fmt,
432
+ ctx.scale, osc, &ctx.stat);
433
+ d[H1(2 * i + 1)] = fcvt_f16_to_fp8(e1, output_fmt,
434
+ ctx.scale, osc, &ctx.stat);
435
+ }
436
+
437
+ fp8_cvt_finish(env, &ctx);
438
+}
439
+
440
void HELPER(advsimd_fcvt_bs)(void *vd, void *vn, void *vm,
441
CPUARMState *env, uint32_t desc)
442
{
target/arm/tcg/helper-fp8-defs.h
+1
@@ -16,5 +16,6 @@ DEF_HELPER_FLAGS_4(sme2_fcvtl_hb, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
16
DEF_HELPER_FLAGS_4(sve2_bfcvtn_bh, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
17
18
DEF_HELPER_FLAGS_5(gvec_fcvt_bh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
19
+DEF_HELPER_FLAGS_4(sve2_fcvtn_bh, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
20
21
DEF_HELPER_FLAGS_5(advsimd_fcvt_bs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32)
target/arm/tcg/sve.decode
+1
@@ -1101,6 +1101,7 @@ BF2CVT 01100101 00 001 000 001111 ..... ..... @rd_rn_e0
1101
BF1CVTLT 01100101 00 001 001 001110 ..... ..... @rd_rn_e0
1102
BF2CVTLT 01100101 00 001 001 001111 ..... ..... @rd_rn_e0
1103
1104
+FCVTN 01100101 00 001 010 001100 ....0 ..... @rd_rnx2 esz=1
1105
BFCVTN 01100101 00 001 010 001110 ....0 ..... @rd_rnx2 esz=1
1106
1107
### SVE FP Compare with Zero Group
target/arm/tcg/translate-sve.c
+2
@@ -4100,6 +4100,8 @@ TRANS_FEAT_STREAMING_IF(BF1CVTLT, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4100
TRANS_FEAT_STREAMING_IF(BF2CVTLT, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4101
do_f8cvt, a, gen_helper_sve2_bfcvt, true, true)
4102
4103
+TRANS_FEAT_STREAMING_IF(FCVTN, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4104
+ do_f8cvt, a, gen_helper_sve2_fcvtn_bh, false, false)
4105
TRANS_FEAT_STREAMING_IF(BFCVTN, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4106
do_f8cvt, a, gen_helper_sve2_bfcvtn_bh, false, false)
4107