From 0f668e0aee650b76eb429f9d49c34b706cdc6486 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 9 Jun 2026 12:21:01 -0700 Subject: [PATCH] target/arm: Implement FDOT (FP8 to FP16) for AdvSIMD Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20260609192110.752384-38-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-features.h | 5 ++++ target/arm/tcg/a64.decode | 2 ++ target/arm/tcg/fp8_helper.c | 39 ++++++++++++++++++++++++++++++++ target/arm/tcg/helper-fp8-defs.h | 3 +++ target/arm/tcg/translate-a64.c | 2 ++ 5 files changed, 51 insertions(+) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 911819bbb0..caae3e51f3 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -1635,6 +1635,11 @@ static inline bool isar_feature_aa64_f8dp4(const ARMISARegisters *id) return FIELD_EX64_IDREG(id, ID_AA64FPFR0, F8DP4); } +static inline bool isar_feature_aa64_f8dp2(const ARMISARegisters *id) +{ + return FIELD_EX64_IDREG(id, ID_AA64FPFR0, F8DP2); +} + /* * Combinations of feature tests, for ease of use with TRANS_FEAT. */ diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode index 08c493c11e..a3e404e7fe 100644 --- a/target/arm/tcg/a64.decode +++ b/target/arm/tcg/a64.decode @@ -1225,6 +1225,7 @@ FMLALL_sb_v 0.00 1110 0.0 rm:5 110001 rn:5 rd:5 \ &rxx idxm=0 idxn=%fmlall_idxn FDOT_sb_v 0.00 1110 000 ..... 11111 1 ..... ..... @qrrr_s +FDOT_hb_v 0.00 1110 010 ..... 11111 1 ..... ..... @qrrr_h ### Advanced SIMD scalar x indexed element @@ -1351,6 +1352,7 @@ FMLALL_sb_vi 0 . 10 1111 0 . ... rm:3 1000 . 0 rn:5 rd:5 \ &rxx idxm=%hlm4 idxn=%fmlall_idxn FDOT_sb_vi 0.00 1111 00 . ..... 0000 . 0 ..... ..... @qrrx_s +FDOT_hb_vi 0.00 1111 01 .. .... 0000 . 0 ..... ..... @qrrx_h # Floating-point conditional select diff --git a/target/arm/tcg/fp8_helper.c b/target/arm/tcg/fp8_helper.c index f54acb03f3..065df24b84 100644 --- a/target/arm/tcg/fp8_helper.c +++ b/target/arm/tcg/fp8_helper.c @@ -768,3 +768,42 @@ void HELPER(gvec_fdot_idx_sb)(void *vd, void *vn, void *vm, clear_tail(vd, oprsz, simd_maxsz(desc)); } + +void HELPER(gvec_fdot_hb)(void *vd, void *vn, void *vm, + CPUARMState *env, uint32_t desc) +{ + FP8MulContext ctx = fp8_mul_start(env, 0xf); + size_t oprsz = simd_oprsz(desc); + size_t nelem = oprsz / 2; + uint16_t *n = vn; + uint16_t *m = vm; + float16 *d = vd; + + for (size_t i = 0; i < nelem; i++) { + d[i] = f8dotadd_h(n[i], m[i], 2, d[i], &ctx); + } + + clear_tail(vd, oprsz, simd_maxsz(desc)); +} + +void HELPER(gvec_fdot_idx_hb)(void *vd, void *vn, void *vm, + CPUARMState *env, uint32_t desc) +{ + FP8MulContext ctx = fp8_mul_start(env, 0xf); + size_t idx = simd_data(desc); + size_t oprsz = simd_oprsz(desc); + size_t nelem = oprsz / 2; + uint16_t *n = vn; + uint16_t *m = vm; + float16 *d = vd; + size_t i = 0; + + do { + uint16_t e1 = m[i + H2(idx)]; + do { + d[i] = f8dotadd_h(n[i], e1, 2, d[i], &ctx); + } while (++i % 8 != 0); + } while (i < nelem); + + clear_tail(vd, oprsz, simd_maxsz(desc)); +} diff --git a/target/arm/tcg/helper-fp8-defs.h b/target/arm/tcg/helper-fp8-defs.h index ee6f2e9236..5995d77577 100644 --- a/target/arm/tcg/helper-fp8-defs.h +++ b/target/arm/tcg/helper-fp8-defs.h @@ -32,3 +32,6 @@ DEF_HELPER_FLAGS_5(gvec_fmla_idx_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, DEF_HELPER_FLAGS_5(gvec_fdot_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) DEF_HELPER_FLAGS_5(gvec_fdot_idx_sb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) + +DEF_HELPER_FLAGS_5(gvec_fdot_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) +DEF_HELPER_FLAGS_5(gvec_fdot_idx_hb, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index ce29176cb7..e4c539fb18 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -7514,6 +7514,7 @@ static bool do_f8dot(DisasContext *s, arg_qrrr_e *a, } TRANS_FEAT(FDOT_sb_v, aa64_f8dp4, do_f8dot, a, gen_helper_gvec_fdot_sb) +TRANS_FEAT(FDOT_hb_v, aa64_f8dp2, do_f8dot, a, gen_helper_gvec_fdot_hb) static bool do_f8dot_idx(DisasContext *s, arg_qrrx_e *a, gen_helper_gvec_3_ptr *fn) @@ -7529,6 +7530,7 @@ static bool do_f8dot_idx(DisasContext *s, arg_qrrx_e *a, } TRANS_FEAT(FDOT_sb_vi, aa64_f8dp4, do_f8dot_idx, a, gen_helper_gvec_fdot_idx_sb) +TRANS_FEAT(FDOT_hb_vi, aa64_f8dp2, do_f8dot_idx, a, gen_helper_gvec_fdot_idx_hb) static bool do_int3_vector_idx(DisasContext *s, arg_qrrx_e *a, gen_helper_gvec_3 * const fns[2])