From: Richard Henderson <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
Reviewed-by: Peter Maydell <[email protected]>
Message-id: [email protected]
Signed-off-by: Peter Maydell <[email protected]>
---
target/arm/tcg/sme.decode | 4 +++
target/arm/tcg/translate-sme.c | 49 ++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/target/arm/tcg/sme.decode b/target/arm/tcg/sme.decode
index e668293efd..4956995924 100644
--- a/target/arm/tcg/sme.decode
+++ b/target/arm/tcg/sme.decode
@@ -445,6 +445,10 @@ FMLS_n1_h 11000001 001 1 .... 0 .. 111 ..... 01 ...
@azz_nx1_o3 n=4
FMLS_n1_s 11000001 001 1 .... 0 .. 110 ..... 01 ... @azz_nx1_o3 n=4
FMLS_n1_d 11000001 011 1 .... 0 .. 110 ..... 01 ... @azz_nx1_o3 n=4
+FMLALL_n1_b 11000001 001 1 .... 0 .. 001 ..... 000 .. @azz_nx1_o2x4 n=1
+FMLALL_n1_b 11000001 001 0 .... 0 .. 000 ..... 0001 . @azz_nx1_o1x4 n=2
+FMLALL_n1_b 11000001 001 1 .... 0 .. 000 ..... 0001 . @azz_nx1_o1x4 n=4
+
### SME2 Multi-vector Multiple Array Vectors
%zn_ax2 6:4 !function=times_2
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
index 63c6e2c9b1..30487c34a0 100644
--- a/target/arm/tcg/translate-sme.c
+++ b/target/arm/tcg/translate-sme.c
@@ -1059,6 +1059,47 @@ static bool do_azz_acc_fp(DisasContext *s, int nreg, int
nsel,
return true;
}
+static bool do_azz_acc_fp8(DisasContext *s, int nreg, int nsel,
+ int rv, int off, int zn, int zm,
+ int data, int shsel, bool multi,
+ gen_helper_gvec_3_ptr *fn)
+{
+ /*
+ * TODO: Could plausibly reuse do_azz_acc_fp, after the fpmr check,
+ * but the fp8 helpers were written without a separate addend operand.
+ */
+ if (fpmr_access_check(s) && sme_smza_enabled_check(s)) {
+ int svl = streaming_vec_reg_size(s);
+ int vstride = svl / nreg;
+ TCGv_ptr t_za = get_zarray(s, rv, off, nreg, nsel);
+ TCGv_ptr t;
+
+ t = tcg_temp_new_ptr();
+
+ for (int r = 0; r < nreg; ++r) {
+ TCGv_ptr t_zn = vec_full_reg_ptr(s, zn);
+ TCGv_ptr t_zm = vec_full_reg_ptr(s, zm);
+
+ for (int i = 0; i < nsel; ++i) {
+ int o_za = (r * vstride + i) * sizeof(ARMVectorReg);
+ int desc = simd_desc(svl, svl, data | (i << shsel));
+
+ tcg_gen_addi_ptr(t, t_za, o_za);
+ fn(t, t_zn, t_zm, tcg_env, tcg_constant_i32(desc));
+ }
+
+ /*
+ * For multiple-and-single vectors, Zn may wrap.
+ * For multiple vectors, both Zn and Zm are aligned.
+ */
+ zn = (zn + 1) % 32;
+ zm += multi;
+ }
+ }
+ return true;
+}
+
+
static bool do_fmlal(DisasContext *s, arg_azz_n *a, bool sub, bool multi)
{
return do_azz_acc_fp(s, a->n, 2, a->rv, a->off, a->zn, a->zm,
@@ -1071,6 +1112,14 @@ TRANS_FEAT(FMLSL_n1, aa64_sme2, do_fmlal, a, true, false)
TRANS_FEAT(FMLAL_nn, aa64_sme2, do_fmlal, a, false, true)
TRANS_FEAT(FMLSL_nn, aa64_sme2, do_fmlal, a, true, true)
+static bool do_fmlall_fp8(DisasContext *s, arg_azz_n *a, bool multi)
+{
+ return do_azz_acc_fp8(s, a->n, 4, a->rv, a->off, a->zn, a->zm,
+ 0, 0, multi, gen_helper_gvec_fmla_sb);
+}
+
+TRANS_FEAT(FMLALL_n1_b, aa64_sme_f8f32, do_fmlall_fp8, a, false)
+
static bool do_fmlal_nx(DisasContext *s, arg_azx_n *a, bool sub)
{
return do_azz_acc_fp(s, a->n, 2, a->rv, a->off, a->zn, a->zm,
--
2.43.0