diff options
author | Peter Maydell | 2021-06-17 14:16:03 +0200 |
---|---|---|
committer | Peter Maydell | 2021-06-21 18:12:51 +0200 |
commit | 1d2386f70a0cb2ad9c5fab2cf1eedb80bb5b313d (patch) | |
tree | 5eabbdb7f2bfc57c99e83553843b8023b1b0efac /target/arm/mve_helper.c | |
parent | target/arm: Implement MVE VMULL (diff) | |
download | qemu-1d2386f70a0cb2ad9c5fab2cf1eedb80bb5b313d.tar.gz qemu-1d2386f70a0cb2ad9c5fab2cf1eedb80bb5b313d.tar.xz qemu-1d2386f70a0cb2ad9c5fab2cf1eedb80bb5b313d.zip |
target/arm: Implement MVE VMLALDAV
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
Diffstat (limited to 'target/arm/mve_helper.c')
-rw-r--r-- | target/arm/mve_helper.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c index a3d09db83b..4d586c4d26 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, +=, +=) |