@samitouri / QOSamiQemu / commits / 446050c4df

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)