diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-09-01 09:02:35 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-09-01 11:08:16 +0100 |
commit | 3173c0dd933cbd80578bde6aa116f8f519174a2e (patch) | |
tree | c1e6ceda56cf783bf1d4c8763a9538b9fcb3dc64 /target | |
parent | 104afc68cf6fbd518e202647e996a14dd0c70130 (diff) | |
download | qemu-3173c0dd933cbd80578bde6aa116f8f519174a2e.zip qemu-3173c0dd933cbd80578bde6aa116f8f519174a2e.tar.gz qemu-3173c0dd933cbd80578bde6aa116f8f519174a2e.tar.bz2 |
target/arm: Implement MVE VFMA and VFMS
Implement the MVE VFMA and VFMS insns.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/helper-mve.h | 6 | ||||
-rw-r--r-- | target/arm/mve.decode | 3 | ||||
-rw-r--r-- | target/arm/mve_helper.c | 37 | ||||
-rw-r--r-- | target/arm/translate-mve.c | 2 |
4 files changed, 48 insertions, 0 deletions
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h index 42eba8e..c230610 100644 --- a/target/arm/helper-mve.h +++ b/target/arm/helper-mve.h @@ -434,6 +434,12 @@ DEF_HELPER_FLAGS_4(mve_vfcadd90s, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) DEF_HELPER_FLAGS_4(mve_vfcadd270h, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) DEF_HELPER_FLAGS_4(mve_vfcadd270s, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vfmah, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vfmas, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) + +DEF_HELPER_FLAGS_4(mve_vfmsh, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vfmss, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) + DEF_HELPER_FLAGS_4(mve_vadd_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vadd_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vadd_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) diff --git a/target/arm/mve.decode b/target/arm/mve.decode index c728c70..3a2056f 100644 --- a/target/arm/mve.decode +++ b/target/arm/mve.decode @@ -639,3 +639,6 @@ VMINNM 1111 1111 0 . 1 . ... 0 ... 0 1111 . 1 . 1 ... 0 @2op_fp VCADD90_fp 1111 1100 1 . 0 . ... 0 ... 0 1000 . 1 . 0 ... 0 @2op_fp_size_rev VCADD270_fp 1111 1101 1 . 0 . ... 0 ... 0 1000 . 1 . 0 ... 0 @2op_fp_size_rev + +VFMA 1110 1111 0 . 0 . ... 0 ... 0 1100 . 1 . 1 ... 0 @2op_fp +VFMS 1110 1111 0 . 1 . ... 0 ... 0 1100 . 1 . 1 ... 0 @2op_fp diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c index 2cc8b3e..d7f250a 100644 --- a/target/arm/mve_helper.c +++ b/target/arm/mve_helper.c @@ -2894,3 +2894,40 @@ DO_VCADD_FP(vfcadd90h, 2, float16, float16_sub, float16_add) DO_VCADD_FP(vfcadd90s, 4, float32, float32_sub, float32_add) DO_VCADD_FP(vfcadd270h, 2, float16, float16_add, float16_sub) DO_VCADD_FP(vfcadd270s, 4, float32, float32_add, float32_sub) + +#define DO_VFMA(OP, ESIZE, TYPE, CHS) \ + void HELPER(glue(mve_, OP))(CPUARMState *env, \ + void *vd, void *vn, void *vm) \ + { \ + TYPE *d = vd, *n = vn, *m = vm; \ + TYPE r; \ + uint16_t mask = mve_element_mask(env); \ + unsigned e; \ + float_status *fpst; \ + float_status scratch_fpst; \ + for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \ + if ((mask & MAKE_64BIT_MASK(0, ESIZE)) == 0) { \ + continue; \ + } \ + fpst = (ESIZE == 2) ? &env->vfp.standard_fp_status_f16 : \ + &env->vfp.standard_fp_status; \ + if (!(mask & 1)) { \ + /* We need the result but without updating flags */ \ + scratch_fpst = *fpst; \ + fpst = &scratch_fpst; \ + } \ + r = n[H##ESIZE(e)]; \ + if (CHS) { \ + r = TYPE##_chs(r); \ + } \ + r = TYPE##_muladd(r, m[H##ESIZE(e)], d[H##ESIZE(e)], \ + 0, fpst); \ + mergemask(&d[H##ESIZE(e)], r, mask); \ + } \ + mve_advance_vpt(env); \ + } + +DO_VFMA(vfmah, 2, float16, false) +DO_VFMA(vfmas, 4, float32, false) +DO_VFMA(vfmsh, 2, float16, true) +DO_VFMA(vfmss, 4, float32, true) diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c index 6203e3f..d61abc6 100644 --- a/target/arm/translate-mve.c +++ b/target/arm/translate-mve.c @@ -854,6 +854,8 @@ DO_2OP_FP(VMAXNM, vmaxnm) DO_2OP_FP(VMINNM, vminnm) DO_2OP_FP(VCADD90_fp, vfcadd90) DO_2OP_FP(VCADD270_fp, vfcadd270) +DO_2OP_FP(VFMA, vfma) +DO_2OP_FP(VFMS, vfms) static bool do_2op_scalar(DisasContext *s, arg_2scalar *a, MVEGenTwoOpScalarFn fn) |