All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 30/57] target/arm: Implement MVE VMLALDAV
Date: Mon, 21 Jun 2021 17:28:06 +0100	[thread overview]
Message-ID: <20210621162833.32535-31-peter.maydell@linaro.org> (raw)
In-Reply-To: <20210621162833.32535-1-peter.maydell@linaro.org>

Implement the MVE VMLALDAV insn, which multiplies pairs of integer
elements, accumulating them into a 64-bit result in a pair of
general-purpose registers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210617121628.20116-20-peter.maydell@linaro.org
---
 target/arm/helper-mve.h    |  8 ++++
 target/arm/translate.h     | 10 ++++
 target/arm/mve.decode      | 15 ++++++
 target/arm/mve_helper.c    | 34 ++++++++++++++
 target/arm/translate-mve.c | 96 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 163 insertions(+)

diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
index 9bbeb7ec49d..0138e28278a 100644
--- a/target/arm/helper-mve.h
+++ b/target/arm/helper-mve.h
@@ -144,3 +144,11 @@ DEF_HELPER_FLAGS_4(mve_vmulltsw, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr)
 DEF_HELPER_FLAGS_4(mve_vmulltub, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr)
 DEF_HELPER_FLAGS_4(mve_vmulltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr)
 DEF_HELPER_FLAGS_4(mve_vmulltuw, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr)
+
+DEF_HELPER_FLAGS_4(mve_vmlaldavsh, TCG_CALL_NO_WG, i64, env, ptr, ptr, i64)
+DEF_HELPER_FLAGS_4(mve_vmlaldavsw, TCG_CALL_NO_WG, i64, env, ptr, ptr, i64)
+DEF_HELPER_FLAGS_4(mve_vmlaldavxsh, TCG_CALL_NO_WG, i64, env, ptr, ptr, i64)
+DEF_HELPER_FLAGS_4(mve_vmlaldavxsw, TCG_CALL_NO_WG, i64, env, ptr, ptr, i64)
+
+DEF_HELPER_FLAGS_4(mve_vmlaldavuh, TCG_CALL_NO_WG, i64, env, ptr, ptr, i64)
+DEF_HELPER_FLAGS_4(mve_vmlaldavuw, TCG_CALL_NO_WG, i64, env, ptr, ptr, i64)
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 2821b325e33..99c917c571a 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -136,6 +136,11 @@ static inline int negate(DisasContext *s, int x)
     return -x;
 }
 
+static inline int plus_1(DisasContext *s, int x)
+{
+    return x + 1;
+}
+
 static inline int plus_2(DisasContext *s, int x)
 {
     return x + 2;
@@ -151,6 +156,11 @@ static inline int times_4(DisasContext *s, int x)
     return x * 4;
 }
 
+static inline int times_2_plus_1(DisasContext *s, int x)
+{
+    return x * 2 + 1;
+}
+
 static inline int arm_dc_feature(DisasContext *dc, int feature)
 {
     return (dc->features & (1ULL << feature)) != 0;
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
index 5a480d61cd6..bde54d05bb9 100644
--- a/target/arm/mve.decode
+++ b/target/arm/mve.decode
@@ -130,3 +130,18 @@ VNEG_fp          1111 1111 1 . 11 .. 01 ... 0 0111 11 . 0 ... 0 @1op
 VDUP             1110 1110 1 1 10 ... 0 .... 1011 . 0 0 1 0000 @vdup size=0
 VDUP             1110 1110 1 0 10 ... 0 .... 1011 . 0 1 1 0000 @vdup size=1
 VDUP             1110 1110 1 0 10 ... 0 .... 1011 . 0 0 1 0000 @vdup size=2
+
+# multiply-add long dual accumulate
+# rdahi: bits [3:1] from insn, bit 0 is 1
+# rdalo: bits [3:1] from insn, bit 0 is 0
+%rdahi 20:3 !function=times_2_plus_1
+%rdalo 13:3 !function=times_2
+# size bit is 0 for 16 bit, 1 for 32 bit
+%size_16 16:1 !function=plus_1
+
+&vmlaldav rdahi rdalo size qn qm x a
+
+@vmlaldav        .... .... . ... ... . ... . .... .... qm:3 . \
+                 qn=%qn rdahi=%rdahi rdalo=%rdalo size=%size_16 &vmlaldav
+VMLALDAV_S       1110 1110 1 ... ... . ... x:1 1110 . 0 a:1 0 ... 0 @vmlaldav
+VMLALDAV_U       1111 1110 1 ... ... . ... x:1 1110 . 0 a:1 0 ... 0 @vmlaldav
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
index a3d09db83b3..4d586c4d26f 100644
--- a/target/arm/mve_helper.c
+++ b/target/arm/mve_helper.c
@@ -488,3 +488,37 @@ DO_2OP_S(vhadds, do_vhadd_s)
 DO_2OP_U(vhaddu, do_vhadd_u)
 DO_2OP_S(vhsubs, do_vhsub_s)
 DO_2OP_U(vhsubu, do_vhsub_u)
+
+
+/*
+ * Multiply add long dual accumulate ops.
+ */
+#define DO_LDAV(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC)                 \
+    uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn,         \
+                                    void *vm, uint64_t a)               \
+    {                                                                   \
+        uint16_t mask = mve_element_mask(env);                          \
+        unsigned e;                                                     \
+        TYPE *n = vn, *m = vm;                                          \
+        for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) {              \
+            if (mask & 1) {                                             \
+                if (e & 1) {                                            \
+                    a ODDACC                                            \
+                        (int64_t)n[H##ESIZE(e - 1 * XCHG)] * m[H##ESIZE(e)]; \
+                } else {                                                \
+                    a EVENACC                                           \
+                        (int64_t)n[H##ESIZE(e + 1 * XCHG)] * m[H##ESIZE(e)]; \
+                }                                                       \
+            }                                                           \
+        }                                                               \
+        mve_advance_vpt(env);                                           \
+        return a;                                                       \
+    }
+
+DO_LDAV(vmlaldavsh, 2, int16_t, false, +=, +=)
+DO_LDAV(vmlaldavxsh, 2, int16_t, true, +=, +=)
+DO_LDAV(vmlaldavsw, 4, int32_t, false, +=, +=)
+DO_LDAV(vmlaldavxsw, 4, int32_t, true, +=, +=)
+
+DO_LDAV(vmlaldavuh, 2, uint16_t, false, +=, +=)
+DO_LDAV(vmlaldavuw, 4, uint32_t, false, +=, +=)
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
index 1cadc3b04da..f8ceeac5a4f 100644
--- a/target/arm/translate-mve.c
+++ b/target/arm/translate-mve.c
@@ -31,6 +31,7 @@
 typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
 typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
 typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
+typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
 
 /* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
 static inline long mve_qreg_offset(unsigned reg)
@@ -88,6 +89,22 @@ static void mve_update_eci(DisasContext *s)
     }
 }
 
+static bool mve_skip_first_beat(DisasContext *s)
+{
+    /* Return true if PSR.ECI says we must skip the first beat of this insn */
+    switch (s->eci) {
+    case ECI_NONE:
+        return false;
+    case ECI_A0:
+    case ECI_A0A1:
+    case ECI_A0A1A2:
+    case ECI_A0A1A2B0:
+        return true;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
 {
     TCGv_i32 addr;
@@ -365,3 +382,82 @@ DO_2OP(VMULL_BS, vmullbs)
 DO_2OP(VMULL_BU, vmullbu)
 DO_2OP(VMULL_TS, vmullts)
 DO_2OP(VMULL_TU, vmulltu)
+
+static bool do_long_dual_acc(DisasContext *s, arg_vmlaldav *a,
+                             MVEGenDualAccOpFn *fn)
+{
+    TCGv_ptr qn, qm;
+    TCGv_i64 rda;
+    TCGv_i32 rdalo, rdahi;
+
+    if (!dc_isar_feature(aa32_mve, s) ||
+        !mve_check_qreg_bank(s, a->qn | a->qm) ||
+        !fn) {
+        return false;
+    }
+    /*
+     * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
+     * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
+     */
+    if (a->rdahi == 13 || a->rdahi == 15) {
+        return false;
+    }
+    if (!mve_eci_check(s) || !vfp_access_check(s)) {
+        return true;
+    }
+
+    qn = mve_qreg_ptr(a->qn);
+    qm = mve_qreg_ptr(a->qm);
+
+    /*
+     * This insn is subject to beat-wise execution. Partial execution
+     * of an A=0 (no-accumulate) insn which does not execute the first
+     * beat must start with the current rda value, not 0.
+     */
+    if (a->a || mve_skip_first_beat(s)) {
+        rda = tcg_temp_new_i64();
+        rdalo = load_reg(s, a->rdalo);
+        rdahi = load_reg(s, a->rdahi);
+        tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
+        tcg_temp_free_i32(rdalo);
+        tcg_temp_free_i32(rdahi);
+    } else {
+        rda = tcg_const_i64(0);
+    }
+
+    fn(rda, cpu_env, qn, qm, rda);
+    tcg_temp_free_ptr(qn);
+    tcg_temp_free_ptr(qm);
+
+    rdalo = tcg_temp_new_i32();
+    rdahi = tcg_temp_new_i32();
+    tcg_gen_extrl_i64_i32(rdalo, rda);
+    tcg_gen_extrh_i64_i32(rdahi, rda);
+    store_reg(s, a->rdalo, rdalo);
+    store_reg(s, a->rdahi, rdahi);
+    tcg_temp_free_i64(rda);
+    mve_update_eci(s);
+    return true;
+}
+
+static bool trans_VMLALDAV_S(DisasContext *s, arg_vmlaldav *a)
+{
+    static MVEGenDualAccOpFn * const fns[4][2] = {
+        { NULL, NULL },
+        { gen_helper_mve_vmlaldavsh, gen_helper_mve_vmlaldavxsh },
+        { gen_helper_mve_vmlaldavsw, gen_helper_mve_vmlaldavxsw },
+        { NULL, NULL },
+    };
+    return do_long_dual_acc(s, a, fns[a->size][a->x]);
+}
+
+static bool trans_VMLALDAV_U(DisasContext *s, arg_vmlaldav *a)
+{
+    static MVEGenDualAccOpFn * const fns[4][2] = {
+        { NULL, NULL },
+        { gen_helper_mve_vmlaldavuh, NULL },
+        { gen_helper_mve_vmlaldavuw, NULL },
+        { NULL, NULL },
+    };
+    return do_long_dual_acc(s, a, fns[a->size][a->x]);
+}
-- 
2.20.1



  parent reply	other threads:[~2021-06-21 16:46 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-21 16:27 [PULL 00/57] target-arm queue Peter Maydell
2021-06-21 16:27 ` [PULL 01/57] hw/acpi: Provide stub version of acpi_ghes_record_errors() Peter Maydell
2021-06-21 16:27 ` [PULL 02/57] hw/acpi: Provide function acpi_ghes_present() Peter Maydell
2021-06-21 16:27 ` [PULL 03/57] target/arm: Use acpi_ghes_present() to see if we report ACPI memory errors Peter Maydell
2021-06-21 16:27 ` [PULL 04/57] docs/system/arm: Document which architecture extensions we emulate Peter Maydell
2021-06-21 16:27 ` [PULL 05/57] target/arm/translate-vfp.c: Whitespace fixes Peter Maydell
2021-06-21 16:27 ` [PULL 06/57] target/arm: Handle FPU being disabled in FPCXT_NS accesses Peter Maydell
2021-06-21 16:27 ` [PULL 07/57] target/arm: Don't NOCP fault for " Peter Maydell
2021-06-21 16:27 ` [PULL 08/57] target/arm: Handle writeback in VLDR/VSTR sysreg with no memory access Peter Maydell
2021-06-21 16:27 ` [PULL 09/57] target/arm: Factor FP context update code out into helper function Peter Maydell
2021-06-21 16:27 ` [PULL 10/57] target/arm: Split vfp_access_check() into A and M versions Peter Maydell
2021-06-21 16:27 ` [PULL 11/57] target/arm: Handle FPU check for FPCXT_NS insns via vfp_access_check_m() Peter Maydell
2021-06-21 16:27 ` [PULL 12/57] target/arm: Implement MVE VLDR/VSTR (non-widening forms) Peter Maydell
2021-06-21 16:27 ` [PULL 13/57] target/arm: Implement widening/narrowing MVE VLDR/VSTR insns Peter Maydell
2021-06-21 16:27 ` [PULL 14/57] target/arm: Implement MVE VCLZ Peter Maydell
2021-06-21 16:27 ` [PULL 15/57] target/arm: Implement MVE VCLS Peter Maydell
2021-06-21 16:27 ` [PULL 16/57] target/arm: Implement MVE VREV16, VREV32, VREV64 Peter Maydell
2021-06-21 16:27 ` [PULL 17/57] target/arm: Implement MVE VMVN (register) Peter Maydell
2021-06-21 16:27 ` [PULL 18/57] target/arm: Implement MVE VABS Peter Maydell
2021-06-21 16:27 ` [PULL 19/57] target/arm: Implement MVE VNEG Peter Maydell
2021-06-21 16:27 ` [PULL 20/57] tcg: Make gen_dup_i32/i64() public as tcg_gen_dup_i32/i64 Peter Maydell
2021-06-21 16:27 ` [PULL 21/57] target/arm: Implement MVE VDUP Peter Maydell
2021-06-21 16:27 ` [PULL 22/57] target/arm: Implement MVE VAND, VBIC, VORR, VORN, VEOR Peter Maydell
2021-06-21 16:27 ` [PULL 23/57] target/arm: Implement MVE VADD, VSUB, VMUL Peter Maydell
2021-06-21 16:28 ` [PULL 24/57] target/arm: Implement MVE VMULH Peter Maydell
2021-06-21 16:28 ` [PULL 25/57] target/arm: Implement MVE VRMULH Peter Maydell
2021-06-21 16:28 ` [PULL 26/57] target/arm: Implement MVE VMAX, VMIN Peter Maydell
2021-06-21 16:28 ` [PULL 27/57] target/arm: Implement MVE VABD Peter Maydell
2021-06-21 16:28 ` [PULL 28/57] target/arm: Implement MVE VHADD, VHSUB Peter Maydell
2021-06-21 16:28 ` [PULL 29/57] target/arm: Implement MVE VMULL Peter Maydell
2021-06-21 16:28 ` Peter Maydell [this message]
2021-06-21 16:28 ` [PULL 31/57] target/arm: Implement MVE VMLSLDAV Peter Maydell
2021-06-21 16:28 ` [PULL 32/57] target/arm: Implement MVE VRMLALDAVH, VRMLSLDAVH Peter Maydell
2021-06-21 16:28 ` [PULL 33/57] target/arm: Implement MVE VADD (scalar) Peter Maydell
2021-06-21 16:28 ` [PULL 34/57] target/arm: Implement MVE VSUB, VMUL (scalar) Peter Maydell
2021-06-21 16:28 ` [PULL 35/57] target/arm: Implement MVE VHADD, VHSUB (scalar) Peter Maydell
2021-06-21 16:28 ` [PULL 36/57] target/arm: Implement MVE VBRSR Peter Maydell
2021-06-21 16:28 ` [PULL 37/57] target/arm: Implement MVE VPST Peter Maydell
2021-06-21 16:28 ` [PULL 38/57] target/arm: Implement MVE VQADD and VQSUB Peter Maydell
2021-06-21 16:28 ` [PULL 39/57] target/arm: Implement MVE VQDMULH and VQRDMULH (scalar) Peter Maydell
2021-06-21 16:28 ` [PULL 40/57] target/arm: Implement MVE VQDMULL scalar Peter Maydell
2021-06-21 16:28 ` [PULL 41/57] target/arm: Implement MVE VQDMULH, VQRDMULH (vector) Peter Maydell
2021-06-21 16:28 ` [PULL 42/57] target/arm: Implement MVE VQADD, VQSUB (vector) Peter Maydell
2021-06-21 16:28 ` [PULL 43/57] target/arm: Implement MVE VQSHL (vector) Peter Maydell
2021-06-21 16:28 ` [PULL 44/57] target/arm: Implement MVE VQRSHL Peter Maydell
2021-06-21 16:28 ` [PULL 45/57] target/arm: Implement MVE VSHL insn Peter Maydell
2021-06-21 16:28 ` [PULL 46/57] target/arm: Implement MVE VRSHL Peter Maydell
2021-06-21 16:28 ` [PULL 47/57] target/arm: Implement MVE VQDMLADH and VQRDMLADH Peter Maydell
2021-06-21 16:28 ` [PULL 48/57] target/arm: Implement MVE VQDMLSDH and VQRDMLSDH Peter Maydell
2021-06-21 16:28 ` [PULL 49/57] target/arm: Implement MVE VQDMULL (vector) Peter Maydell
2021-06-21 16:28 ` [PULL 50/57] target/arm: Implement MVE VRHADD Peter Maydell
2021-06-21 16:28 ` [PULL 51/57] target/arm: Implement MVE VADC, VSBC Peter Maydell
2021-06-21 16:28 ` [PULL 52/57] target/arm: Implement MVE VCADD Peter Maydell
2021-06-21 16:28 ` [PULL 53/57] target/arm: Implement MVE VHCADD Peter Maydell
2021-06-21 16:28 ` [PULL 54/57] target/arm: Implement MVE VADDV Peter Maydell
2021-06-21 16:28 ` [PULL 55/57] target/arm: Make VMOV scalar <-> gpreg beatwise for MVE Peter Maydell
2021-06-21 16:28 ` [PULL 56/57] target/arm: Implement MTE3 Peter Maydell
2021-06-21 16:28 ` [PULL 57/57] docs/system: arm: Add nRF boards description Peter Maydell
2021-06-21 17:25 ` [PULL 00/57] target-arm queue no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210621162833.32535-31-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.