target/arm: SVE2 FMAXP, FMINP must honour AH=1
The behaviour of floating-point maximum and minimum insns has some odd special cases when FPCR.AH=1. We get this right in most places (for instance, the ASIMD FMAXP, FMINP) but forgot about it for the SVE2 versions of FMAXP and FMINP. Cc: qemu-stable@nongnu.org Fixes: 384433e70983 ("target/arm: Implement FPCR.AH semantics for FMINP and FMAXP") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20260521122913.1565011-2-peter.maydell@linaro.org
Peter Maydell committed
May 21, 2026 at 13:29 UTC
446050c4dfe4566ae3fcba9c6588c89a66ed4b33
3 files changed
+24
-2
target/arm/tcg/helper-sve-defs.h
+14
@@ -2914,6 +2914,20 @@ DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_s, TCG_CALL_NO_RWG,
2914
DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_d, TCG_CALL_NO_RWG,
2915
void, ptr, ptr, ptr, ptr, fpst, i32)
2916
2917
+DEF_HELPER_FLAGS_6(sve2_ah_fmaxp_zpzz_h, TCG_CALL_NO_RWG,
2918
+ void, ptr, ptr, ptr, ptr, fpst, i32)
2919
+DEF_HELPER_FLAGS_6(sve2_ah_fmaxp_zpzz_s, TCG_CALL_NO_RWG,
2920
+ void, ptr, ptr, ptr, ptr, fpst, i32)
2921
+DEF_HELPER_FLAGS_6(sve2_ah_fmaxp_zpzz_d, TCG_CALL_NO_RWG,
2922
+ void, ptr, ptr, ptr, ptr, fpst, i32)
2923
+
2924
+DEF_HELPER_FLAGS_6(sve2_ah_fminp_zpzz_h, TCG_CALL_NO_RWG,
2925
+ void, ptr, ptr, ptr, ptr, fpst, i32)
2926
+DEF_HELPER_FLAGS_6(sve2_ah_fminp_zpzz_s, TCG_CALL_NO_RWG,
2927
+ void, ptr, ptr, ptr, ptr, fpst, i32)
2928
+DEF_HELPER_FLAGS_6(sve2_ah_fminp_zpzz_d, TCG_CALL_NO_RWG,
2929
+ void, ptr, ptr, ptr, ptr, fpst, i32)
2930
+
2931
DEF_HELPER_FLAGS_5(sve2_eor3, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
2932
DEF_HELPER_FLAGS_5(sve2_bcax, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
2933
DEF_HELPER_FLAGS_5(sve2_bsl1n, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
target/arm/tcg/sve_helper.c
+8
@@ -778,6 +778,14 @@ DO_ZPZZ_PAIR_FP(sve2_fminp_zpzz_h, float16, H1_2, float16_min)
778
DO_ZPZZ_PAIR_FP(sve2_fminp_zpzz_s, float32, H1_4, float32_min)
779
DO_ZPZZ_PAIR_FP(sve2_fminp_zpzz_d, float64, H1_8, float64_min)
780
781
+DO_ZPZZ_PAIR_FP(sve2_ah_fmaxp_zpzz_h, float16, H1_2, helper_vfp_ah_maxh)
782
+DO_ZPZZ_PAIR_FP(sve2_ah_fmaxp_zpzz_s, float32, H1_4, helper_vfp_ah_maxs)
783
+DO_ZPZZ_PAIR_FP(sve2_ah_fmaxp_zpzz_d, float64, H1_8, helper_vfp_ah_maxd)
784
+
785
+DO_ZPZZ_PAIR_FP(sve2_ah_fminp_zpzz_h, float16, H1_2, helper_vfp_ah_minh)
786
+DO_ZPZZ_PAIR_FP(sve2_ah_fminp_zpzz_s, float32, H1_4, helper_vfp_ah_mins)
787
+DO_ZPZZ_PAIR_FP(sve2_ah_fminp_zpzz_d, float64, H1_8, helper_vfp_ah_mind)
788
+
789
#undef DO_ZPZZ_PAIR_FP
790
791
/* Three-operand expander, controlled by a predicate, in which the
target/arm/tcg/translate-sve.c
+2
-2
@@ -7667,8 +7667,8 @@ TRANS_FEAT_NONSTREAMING(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz,
7667
DO_ZPZZ_FP(FADDP, aa64_sme_or_sve2, sve2_faddp_zpzz)
7668
DO_ZPZZ_FP(FMAXNMP, aa64_sme_or_sve2, sve2_fmaxnmp_zpzz)
7669
DO_ZPZZ_FP(FMINNMP, aa64_sme_or_sve2, sve2_fminnmp_zpzz)
7670
-DO_ZPZZ_FP(FMAXP, aa64_sme_or_sve2, sve2_fmaxp_zpzz)
7671
-DO_ZPZZ_FP(FMINP, aa64_sme_or_sve2, sve2_fminp_zpzz)
7670
+DO_ZPZZ_AH_FP(FMAXP, aa64_sme_or_sve2, sve2_fmaxp_zpzz, sve2_ah_fmaxp_zpzz)
7671
+DO_ZPZZ_AH_FP(FMINP, aa64_sme_or_sve2, sve2_fminp_zpzz, sve2_ah_fminp_zpzz)
7672
7673
static bool do_fmmla(DisasContext *s, arg_rrrr_esz *a,
7674
gen_helper_gvec_4_ptr *fn)