As with I8MM, the BF16 field of ID_AA64ZFR0_EL1 is set when the CPU implements FEAT_BF16 and either FEAT_SVE or FEAT_SME, so we need to have separate checks for "(SVE || SME) && BF16" and "SVE && BF16". Follow the same pattern as with I8MM:
* aa64_sve_sme_bf16 means (SVE || SME) && BF16 * aa64_sve_bf16 means (SVE && BF16) BFMMLA is the only SVE BF16 insn that isn't in SME. Signed-off-by: Peter Maydell <[email protected]> --- target/arm/cpu-features.h | 7 ++++++- target/arm/tcg/translate-sve.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 8b8de5db04..1bcf28ab08 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -1434,7 +1434,7 @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id) return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BITPERM) != 0; } -static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id) +static inline bool isar_feature_aa64_sme_sve_bf16(const ARMISARegisters *id) { return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BFLOAT16) != 0; } @@ -1548,6 +1548,11 @@ static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id) return isar_feature_aa64_sve(id) && isar_feature_aa64_sme_sve_i8mm(id); } +static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id) +{ + return isar_feature_aa64_sve(id) && isar_feature_aa64_sme_sve_bf16(id); +} + /* * Feature tests for "does this exist in either 32-bit or 64-bit?" */ diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c index 53d35f6de9..956ddee123 100644 --- a/target/arm/tcg/translate-sve.c +++ b/target/arm/tcg/translate-sve.c @@ -4430,7 +4430,7 @@ TRANS_FEAT(FCVT_sh, aa64_sme_or_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_hs, aa64_sme_or_sve, gen_gvec_fpst_arg_zpz, gen_helper_sve_fcvt_hs, a, 0, FPST_A64_F16) -TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, +TRANS_FEAT(BFCVT, aa64_sme_sve_bf16, gen_gvec_fpst_arg_zpz, gen_helper_sve_bfcvt, a, 0, s->fpcr_ah ? FPST_AH : FPST_A64) @@ -7818,7 +7818,7 @@ TRANS_FEAT(FCVTNT_sh, aa64_sme_or_sve2, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTNT_ds, aa64_sme_or_sve2, gen_gvec_fpst_arg_zpz, gen_helper_sve2_fcvtnt_ds, a, 0, FPST_A64) -TRANS_FEAT(BFCVTNT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, +TRANS_FEAT(BFCVTNT, aa64_sme_sve_bf16, gen_gvec_fpst_arg_zpz, gen_helper_sve_bfcvtnt, a, 0, s->fpcr_ah ? FPST_AH : FPST_A64) @@ -7875,9 +7875,9 @@ TRANS_FEAT(FDOT_zzzz, aa64_sme2_or_sve2p1, gen_gvec_env_arg_zzzz, TRANS_FEAT(FDOT_zzxz, aa64_sme2_or_sve2p1, gen_gvec_env_arg_zzxz, gen_helper_sme2_fdot_idx_h, a) -TRANS_FEAT(BFDOT_zzzz, aa64_sve_bf16, gen_gvec_env_arg_zzzz, +TRANS_FEAT(BFDOT_zzzz, aa64_sme_sve_bf16, gen_gvec_env_arg_zzzz, gen_helper_gvec_bfdot, a, 0) -TRANS_FEAT(BFDOT_zzxz, aa64_sve_bf16, gen_gvec_env_arg_zzxz, +TRANS_FEAT(BFDOT_zzxz, aa64_sme_sve_bf16, gen_gvec_env_arg_zzxz, gen_helper_gvec_bfdot_idx, a) TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_env_arg_zzzz, @@ -7890,8 +7890,8 @@ static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel) s->fpcr_ah ? FPST_AH : FPST_A64); } -TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false) -TRANS_FEAT(BFMLALT_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, true) +TRANS_FEAT(BFMLALB_zzzw, aa64_sme_sve_bf16, do_BFMLAL_zzzw, a, false) +TRANS_FEAT(BFMLALT_zzzw, aa64_sme_sve_bf16, do_BFMLAL_zzzw, a, true) static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel) { @@ -7901,8 +7901,8 @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel) s->fpcr_ah ? FPST_AH : FPST_A64); } -TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false) -TRANS_FEAT(BFMLALT_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, true) +TRANS_FEAT(BFMLALB_zzxw, aa64_sme_sve_bf16, do_BFMLAL_zzxw, a, false) +TRANS_FEAT(BFMLALT_zzxw, aa64_sme_sve_bf16, do_BFMLAL_zzxw, a, true) static bool do_BFMLSL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel) { -- 2.43.0
