From: Richard Henderson Date: Thu, 2 Jul 2026 20:43:05 +0000 (-0700) Subject: target/arm: Implement FMOP4 (widening, 2-way fp16 to fp32) X-Git-Tag: v11.1.0-rc0~26^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae1e896a599847f53da33bf3c7ef211fcdafa346;p=thirdparty%2Fqemu.git target/arm: Implement FMOP4 (widening, 2-way fp16 to fp32) Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20260702204314.79224-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- diff --git a/target/arm/tcg/helper-sme-defs.h b/target/arm/tcg/helper-sme-defs.h index 0e4bb12b38..780b8f162a 100644 --- a/target/arm/tcg/helper-sme-defs.h +++ b/target/arm/tcg/helper-sme-defs.h @@ -375,3 +375,7 @@ DEF_HELPER_FLAGS_5(sme_ah_bfmop4s_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst DEF_HELPER_FLAGS_5(sme_bfmop4a_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) DEF_HELPER_FLAGS_5(sme_bfmop4s_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) DEF_HELPER_FLAGS_5(sme_ah_bfmop4s_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) + +DEF_HELPER_FLAGS_5(sme_fmop4a_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) +DEF_HELPER_FLAGS_5(sme_fmop4s_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) +DEF_HELPER_FLAGS_5(sme_ah_fmop4s_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, env, i32) diff --git a/target/arm/tcg/sme.decode b/target/arm/tcg/sme.decode index 12a3a61432..ea9f459e38 100644 --- a/target/arm/tcg/sme.decode +++ b/target/arm/tcg/sme.decode @@ -1107,3 +1107,4 @@ FMOP4_ss 1000 0000 000. ...0 0000 00.. ..0. 00.. @mop4_o2 FMOP4_dd 1000 0000 110. ...0 0000 00.. ..0. 1... @mop4_o3 BFMOP4_sh 1000 0001 000. ...0 0000 00.. ..0. 00.. @mop4_o2 +FMOP4_sh 1000 0001 001. ...0 0000 00.. ..0. 00.. @mop4_o2 diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c index 5a661ca616..123f459342 100644 --- a/target/arm/tcg/sme_helper.c +++ b/target/arm/tcg/sme_helper.c @@ -2887,3 +2887,54 @@ void HELPER(sme_ah_bfmop4s_sh)(void *vza, void *vzn, void *vzm, is_ebf(env, &fpst) ? inner_ebf_ah_bfmop4s_sh : inner_ah_bfmop4s_sh); } + +static void inner_fmop4a_sh(void *vd, void *vn, void *vm, void *vinfo) +{ + float32 *d = vd; + uint32_t *n = vn, *m = vm; + CPUArchState *env = vinfo; + + *d = f16_dotadd(*d, *n, *m, + &env->vfp.fp_status[FPST_ZA_F16], + &env->vfp.fp_status[FPST_ZA]); +} + +void HELPER(sme_fmop4a_sh)(void *vza, void *vzn, void *vzm, + CPUArchState *env, uint32_t desc) +{ + sme_mop4(vza, vzn, vzm, env, desc, sizeof(float32), inner_fmop4a_sh); +} + +static void inner_fmop4s_sh(void *vd, void *vn, void *vm, void *vinfo) +{ + float32 *d = vd; + uint32_t *n = vn, *m = vm; + CPUArchState *env = vinfo; + + *d = f16_dotadd(*d, *n ^ 0x80008000u, *m, + &env->vfp.fp_status[FPST_ZA_F16], + &env->vfp.fp_status[FPST_ZA]); +} + +void HELPER(sme_fmop4s_sh)(void *vza, void *vzn, void *vzm, + CPUArchState *env, uint32_t desc) +{ + sme_mop4(vza, vzn, vzm, env, desc, sizeof(float32), inner_fmop4s_sh); +} + +static void inner_ah_fmop4s_sh(void *vd, void *vn, void *vm, void *vinfo) +{ + float32 *d = vd; + uint32_t *n = vn, *m = vm; + CPUArchState *env = vinfo; + + *d = f16_dotadd(*d, f16mop_ah_neg_adj_pair(*n, -1), *m, + &env->vfp.fp_status[FPST_ZA_F16], + &env->vfp.fp_status[FPST_ZA]); +} + +void HELPER(sme_ah_fmop4s_sh)(void *vza, void *vzn, void *vzm, + CPUArchState *env, uint32_t desc) +{ + sme_mop4(vza, vzn, vzm, env, desc, sizeof(float32), inner_ah_fmop4s_sh); +} diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c index df4a5c2125..544a825595 100644 --- a/target/arm/tcg/translate-sme.c +++ b/target/arm/tcg/translate-sme.c @@ -2065,3 +2065,10 @@ static gen_helper_gvec_3_ptr * const bfmop4_sh[3] = { gen_helper_sme_ah_bfmop4s_sh }; TRANS_FEAT(BFMOP4_sh, aa64_sme_mop4, do_mop4_fp, a, MO_32, FPST_ENV, bfmop4_sh) + +static gen_helper_gvec_3_ptr * const fmop4_sh[3] = { + gen_helper_sme_fmop4a_sh, + gen_helper_sme_fmop4s_sh, + gen_helper_sme_ah_fmop4s_sh +}; +TRANS_FEAT(FMOP4_sh, aa64_sme_mop4, do_mop4_fp, a, MO_32, FPST_ENV, fmop4_sh)