Commit f2bfb1cf35 for qemu.org
commit f2bfb1cf35bd9684adbe6305b433de15cb7162ef
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Wed Aug 26 10:41:57 2026 -0700
target/arm: Split decode of BFloat SVE FADD, FSUB, FMUL, FMIN*, FMAX*
Split decode so that feature detection can be handled
external to gen_gvec_fpst_arg_zpzz
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20260826174213.614571-11-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode
index bdc2b7f0c0..07dac681ac 100644
--- a/target/arm/tcg/sve.decode
+++ b/target/arm/tcg/sve.decode
@@ -159,6 +159,9 @@
@rd_pg4_rn_rm ........ esz:2 . rm:5 .. pg:4 rn:5 rd:5 &rprr_esz
@pd_pg_rn_rm ........ esz:2 . rm:5 ... pg:3 rn:5 . rd:4 &rprr_esz
+@rdn_pg_rm_e0 ........ .. ... ... ... pg:3 rm:5 rd:5 \
+ &rprr_esz esz=0 rn=%reg_movprfx
+
# Three register operand, with governing predicate, vector element size
@rda_pg_rn_rm ........ esz:2 . rm:5 ... pg:3 rn:5 rd:5 \
&rprrr_esz ra=%reg_movprfx
@@ -1163,14 +1166,35 @@ FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
### SVE FP Arithmetic Predicated Group
# SVE floating-point arithmetic (predicated)
-FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm
-FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm
-FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm
+{
+ BFADD_zpzz 01100101 00 00 0000 100 ... ..... ..... @rdn_pg_rm_e0
+ FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm
+}
+{
+ BFSUB_zpzz 01100101 00 00 0001 100 ... ..... ..... @rdn_pg_rm_e0
+ FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm
+}
+{
+ BFMUL_zpzz 01100101 00 00 0010 100 ... ..... ..... @rdn_pg_rm_e0
+ FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm
+}
FSUB_zpzz 01100101 .. 00 0011 100 ... ..... ..... @rdm_pg_rn # FSUBR
-FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm
-FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm
-FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm
-FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm
+{
+ BFMAXNM_zpzz 01100101 00 00 0100 100 ... ..... ..... @rdn_pg_rm_e0
+ FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm
+}
+{
+ BFMINNM_zpzz 01100101 00 00 0101 100 ... ..... ..... @rdn_pg_rm_e0
+ FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm
+}
+{
+ BFMAX_zpzz 01100101 00 00 0110 100 ... ..... ..... @rdn_pg_rm_e0
+ FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm
+}
+{
+ BFMIN_zpzz 01100101 00 00 0111 100 ... ..... ..... @rdn_pg_rm_e0
+ FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm
+}
FABD 01100101 .. 00 1000 100 ... ..... ..... @rdn_pg_rm
FSCALE 01100101 .. 00 1001 100 ... ..... ..... @rdn_pg_rm
FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index f65c2b0af5..0ad0aff050 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -412,10 +412,6 @@ static bool gen_gvec_fpst_zzzp(DisasContext *s, gen_helper_gvec_4_ptr *fn,
static bool gen_gvec_fpst_arg_zpzz(DisasContext *s, gen_helper_gvec_4_ptr *fn,
arg_rprr_esz *a)
{
- /* These insns use MO_8 to encode BFloat16. */
- if (a->esz == MO_8 && !dc_isar_feature(aa64_sve_b16b16, s)) {
- return false;
- }
return gen_gvec_fpst_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0,
a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
}
@@ -4426,65 +4422,79 @@ TRANS_FEAT_NONSTREAMING(FTSMUL, aa64_sve, gen_gvec_fpst_arg_zzz,
*/
static gen_helper_gvec_4_ptr * const sve_fadd_zpzz_fns[4] = {
- gen_helper_sve_fadd_b16,
+ NULL,
gen_helper_sve_fadd_h,
gen_helper_sve_fadd_s,
gen_helper_sve_fadd_d
};
+TRANS_FEAT(BFADD_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ gen_helper_sve_fadd_b16, a)
TRANS_FEAT(FADD_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fadd_zpzz_fns[a->esz], a)
static gen_helper_gvec_4_ptr * const sve_fsub_zpzz_fns[4] = {
- gen_helper_sve_fsub_b16,
+ NULL,
gen_helper_sve_fsub_h,
gen_helper_sve_fsub_s,
gen_helper_sve_fsub_d
};
+TRANS_FEAT(BFSUB_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ gen_helper_sve_fsub_b16, a)
TRANS_FEAT(FSUB_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fsub_zpzz_fns[a->esz], a)
static gen_helper_gvec_4_ptr * const sve_fmul_zpzz_fns[4] = {
- gen_helper_sve_fmul_b16,
+ NULL,
gen_helper_sve_fmul_h,
gen_helper_sve_fmul_s,
gen_helper_sve_fmul_d
};
+TRANS_FEAT(BFMUL_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ gen_helper_sve_fmul_b16, a)
TRANS_FEAT(FMUL_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fmul_zpzz_fns[a->esz], a)
static gen_helper_gvec_4_ptr * const sve_fmin_fns[4][2] = {
- { gen_helper_sve_fmin_b16, gen_helper_sve_ah_fmin_b16 },
+ { NULL, NULL },
{ gen_helper_sve_fmin_h, gen_helper_sve_ah_fmin_h },
{ gen_helper_sve_fmin_s, gen_helper_sve_ah_fmin_s },
{ gen_helper_sve_fmin_d, gen_helper_sve_ah_fmin_d },
};
+TRANS_FEAT(BFMIN_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ s->fpcr_ah ? gen_helper_sve_ah_fmin_b16 : gen_helper_sve_fmin_b16, a)
TRANS_FEAT(FMIN_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fmin_fns[a->esz][s->fpcr_ah], a)
static gen_helper_gvec_4_ptr * const sve_fmax_fns[4][2] = {
- { gen_helper_sve_fmax_b16, gen_helper_sve_ah_fmax_b16 },
+ { NULL, NULL },
{ gen_helper_sve_fmax_h, gen_helper_sve_ah_fmax_h },
{ gen_helper_sve_fmax_s, gen_helper_sve_ah_fmax_s },
{ gen_helper_sve_fmax_d, gen_helper_sve_ah_fmax_d },
};
+TRANS_FEAT(BFMAX_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ s->fpcr_ah ? gen_helper_sve_ah_fmax_b16 : gen_helper_sve_fmax_b16, a)
TRANS_FEAT(FMAX_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fmax_fns[a->esz][s->fpcr_ah], a)
static gen_helper_gvec_4_ptr * const sve_fmaxnum_fns[4] = {
- gen_helper_sve_fmaxnum_b16,
+ NULL,
gen_helper_sve_fmaxnum_h,
gen_helper_sve_fmaxnum_s,
gen_helper_sve_fmaxnum_d
};
+TRANS_FEAT(BFMAXNM_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ gen_helper_sve_fmaxnum_b16, a)
TRANS_FEAT(FMAXNM_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fmaxnum_fns[a->esz], a)
static gen_helper_gvec_4_ptr * const sve_fminnum_fns[4] = {
- gen_helper_sve_fminnum_b16,
+ NULL,
gen_helper_sve_fminnum_h,
gen_helper_sve_fminnum_s,
gen_helper_sve_fminnum_d
};
+TRANS_FEAT(BFMINNM_zpzz, aa64_sve_b16b16, gen_gvec_fpst_arg_zpzz,
+ gen_helper_sve_fminnum_b16, a)
TRANS_FEAT(FMINNM_zpzz, aa64_sme_or_sve, gen_gvec_fpst_arg_zpzz,
sve_fminnum_fns[a->esz], a)