return isar_feature_aa64_sme(id) || isar_feature_aa64_sve2(id);
}
+static inline bool isar_feature_aa64_sme2_or_sve2(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_sme2(id) || isar_feature_aa64_sve2(id);
+}
+
static inline bool isar_feature_aa64_sme_or_sve2p1(const ARMISARegisters *id)
{
return isar_feature_aa64_sme(id) || isar_feature_aa64_sve2p1(id);
return isar_feature_aa64_sve(id) && isar_feature_aa64_sme_sve_bf16(id);
}
+static inline bool
+isar_feature_aa64_sme2_or_sve2_faminmax(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_sme2_or_sve2(id) && isar_feature_aa64_faminmax(id);
+}
+
/*
* Feature tests for "does this exist in either 32-bit or 64-bit?"
*/
DEF_HELPER_FLAGS_5(sve2p1_st1ss_be_c, TCG_CALL_NO_WG, void, env, ptr, tl, i32, i64)
DEF_HELPER_FLAGS_5(sve2p1_st1dd_le_c, TCG_CALL_NO_WG, void, env, ptr, tl, i32, i64)
DEF_HELPER_FLAGS_5(sve2p1_st1dd_be_c, TCG_CALL_NO_WG, void, env, ptr, tl, i32, i64)
+
+DEF_HELPER_FLAGS_6(sve2_famax_h, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, fpst, i32)
+DEF_HELPER_FLAGS_6(sve2_famax_s, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, fpst, i32)
+DEF_HELPER_FLAGS_6(sve2_famax_d, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, fpst, i32)
+
+DEF_HELPER_FLAGS_6(sve2_famin_h, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, fpst, i32)
+DEF_HELPER_FLAGS_6(sve2_famin_s, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, fpst, i32)
+DEF_HELPER_FLAGS_6(sve2_famin_d, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, fpst, i32)
FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
+FAMAX 01100101 .. 00 1110 100 ... ..... ..... @rdn_pg_rm
+FAMIN 01100101 .. 00 1111 100 ... ..... ..... @rdn_pg_rm
# SVE floating-point arithmetic with immediate (predicated)
FADD_zpzi 01100101 .. 011 000 100 ... 0000 . ..... @rdn_i1
DO_ZPZZ_FP(sve_fmulx_s, uint32_t, H1_4, helper_vfp_mulxs)
DO_ZPZZ_FP(sve_fmulx_d, uint64_t, H1_8, helper_vfp_mulxd)
+DO_ZPZZ_FP(sve2_famax_h, uint16_t, H1_2, float16_famax)
+DO_ZPZZ_FP(sve2_famax_s, uint32_t, H1_4, float32_famax)
+DO_ZPZZ_FP(sve2_famax_d, uint64_t, H1_8, float64_famax)
+
+DO_ZPZZ_FP(sve2_famin_h, uint16_t, H1_2, float16_famin)
+DO_ZPZZ_FP(sve2_famin_s, uint32_t, H1_4, float32_famin)
+DO_ZPZZ_FP(sve2_famin_d, uint64_t, H1_8, float64_famin)
+
#undef DO_ZPZZ_FP
/* Three-operand expander, with one scalar operand, controlled by
DO_ZPZZ_FP(FDIV, aa64_sme_or_sve, sve_fdiv)
DO_ZPZZ_FP(FMULX, aa64_sme_or_sve, sve_fmulx)
+static gen_helper_gvec_4_ptr * const sve2_famax_zpzz_fns[4] = {
+ NULL,
+ gen_helper_sve2_famax_h,
+ gen_helper_sve2_famax_s,
+ gen_helper_sve2_famax_d
+};
+TRANS_FEAT_STREAMING_SME2(FAMAX, aa64_sme2_or_sve2_faminmax,
+ gen_gvec_fpst_arg_zpzz,
+ sve2_famax_zpzz_fns[a->esz], a)
+
+static gen_helper_gvec_4_ptr * const sve2_famin_zpzz_fns[4] = {
+ NULL,
+ gen_helper_sve2_famin_h,
+ gen_helper_sve2_famin_s,
+ gen_helper_sve2_famin_d
+};
+TRANS_FEAT_STREAMING_SME2(FAMIN, aa64_sme2_or_sve2_faminmax,
+ gen_gvec_fpst_arg_zpzz,
+ sve2_famin_zpzz_fns[a->esz], a)
+
typedef void gen_helper_sve_fp2scalar(TCGv_ptr, TCGv_ptr, TCGv_ptr,
TCGv_i64, TCGv_ptr, TCGv_i32);
static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
{ return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); }
+/* For SVE insns which are not valid in Streaming SVE mode */
#define TRANS_FEAT_NONSTREAMING(NAME, FEAT, FUNC, ...) \
static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
{ \
return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); \
}
+/*
+ * For SVE insns which are only valid in Streaming SVE mode when
+ * SME2 is implemented
+ */
+#define TRANS_FEAT_STREAMING_SME2(NAME, FEAT, FUNC, ...) \
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
+ { \
+ s->is_nonstreaming = !dc_isar_feature(aa64_sme2, s); \
+ return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); \
+ }
+
#endif /* TARGET_ARM_TRANSLATE_H */