From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 04/23] target/arm: Convert Neon 3-reg-diff VABAL, VABDL to decodetree
Date: Tue, 16 Jun 2020 10:56:43 +0100 [thread overview]
Message-ID: <20200616095702.25848-5-peter.maydell@linaro.org> (raw)
In-Reply-To: <20200616095702.25848-1-peter.maydell@linaro.org>
Convert the Neon 3-reg-diff insns VABAL and VABDL to decodetree.
Like almost all the remaining insns in this group, these are
a combination of a two-input operation which returns a double width
result and then a possible accumulation of that double width
result into the destination.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/translate.h | 1 +
target/arm/neon-dp.decode | 6 ++
target/arm/translate-neon.inc.c | 132 ++++++++++++++++++++++++++++++++
target/arm/translate.c | 31 +-------
4 files changed, 142 insertions(+), 28 deletions(-)
diff --git a/target/arm/translate.h b/target/arm/translate.h
index c937dfe9bf0..62ed5c4780c 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -371,6 +371,7 @@ typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
+typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
index a2234dfa4f3..4f0aaaf6bb2 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/neon-dp.decode
@@ -442,7 +442,13 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
VADDHN_3d 1111 001 0 1 . .. .... .... 0100 . 0 . 0 .... @3diff
VRADDHN_3d 1111 001 1 1 . .. .... .... 0100 . 0 . 0 .... @3diff
+ VABAL_S_3d 1111 001 0 1 . .. .... .... 0101 . 0 . 0 .... @3diff
+ VABAL_U_3d 1111 001 1 1 . .. .... .... 0101 . 0 . 0 .... @3diff
+
VSUBHN_3d 1111 001 0 1 . .. .... .... 0110 . 0 . 0 .... @3diff
VRSUBHN_3d 1111 001 1 1 . .. .... .... 0110 . 0 . 0 .... @3diff
+
+ VABDL_S_3d 1111 001 0 1 . .. .... .... 0111 . 0 . 0 .... @3diff
+ VABDL_U_3d 1111 001 1 1 . .. .... .... 0111 . 0 . 0 .... @3diff
]
}
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
index 0c3965802a5..bea9360ce3f 100644
--- a/target/arm/translate-neon.inc.c
+++ b/target/arm/translate-neon.inc.c
@@ -2019,3 +2019,135 @@ DO_NARROW_3D(VADDHN, add, narrow, tcg_gen_extrh_i64_i32)
DO_NARROW_3D(VSUBHN, sub, narrow, tcg_gen_extrh_i64_i32)
DO_NARROW_3D(VRADDHN, add, narrow_round, gen_narrow_round_high_u32)
DO_NARROW_3D(VRSUBHN, sub, narrow_round, gen_narrow_round_high_u32)
+
+static bool do_long_3d(DisasContext *s, arg_3diff *a,
+ NeonGenTwoOpWidenFn *opfn,
+ NeonGenTwo64OpFn *accfn)
+{
+ /*
+ * 3-regs different lengths, long operations.
+ * These perform an operation on two inputs that returns a double-width
+ * result, and then possibly perform an accumulation operation of
+ * that result into the double-width destination.
+ */
+ TCGv_i64 rd0, rd1, tmp;
+ TCGv_i32 rn, rm;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if (!opfn) {
+ /* size == 3 case, which is an entirely different insn group */
+ return false;
+ }
+
+ if (a->vd & 1) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ rd0 = tcg_temp_new_i64();
+ rd1 = tcg_temp_new_i64();
+
+ rn = neon_load_reg(a->vn, 0);
+ rm = neon_load_reg(a->vm, 0);
+ opfn(rd0, rn, rm);
+ tcg_temp_free_i32(rn);
+ tcg_temp_free_i32(rm);
+
+ rn = neon_load_reg(a->vn, 1);
+ rm = neon_load_reg(a->vm, 1);
+ opfn(rd1, rn, rm);
+ tcg_temp_free_i32(rn);
+ tcg_temp_free_i32(rm);
+
+ /* Don't store results until after all loads: they might overlap */
+ if (accfn) {
+ tmp = tcg_temp_new_i64();
+ neon_load_reg64(tmp, a->vd);
+ accfn(tmp, tmp, rd0);
+ neon_store_reg64(tmp, a->vd);
+ neon_load_reg64(tmp, a->vd + 1);
+ accfn(tmp, tmp, rd1);
+ neon_store_reg64(tmp, a->vd + 1);
+ tcg_temp_free_i64(tmp);
+ } else {
+ neon_store_reg64(rd0, a->vd);
+ neon_store_reg64(rd1, a->vd + 1);
+ }
+
+ tcg_temp_free_i64(rd0);
+ tcg_temp_free_i64(rd1);
+
+ return true;
+}
+
+static bool trans_VABDL_S_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ gen_helper_neon_abdl_s16,
+ gen_helper_neon_abdl_s32,
+ gen_helper_neon_abdl_s64,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], NULL);
+}
+
+static bool trans_VABDL_U_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ gen_helper_neon_abdl_u16,
+ gen_helper_neon_abdl_u32,
+ gen_helper_neon_abdl_u64,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], NULL);
+}
+
+static bool trans_VABAL_S_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ gen_helper_neon_abdl_s16,
+ gen_helper_neon_abdl_s32,
+ gen_helper_neon_abdl_s64,
+ NULL,
+ };
+ static NeonGenTwo64OpFn * const addfn[] = {
+ gen_helper_neon_addl_u16,
+ gen_helper_neon_addl_u32,
+ tcg_gen_add_i64,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], addfn[a->size]);
+}
+
+static bool trans_VABAL_U_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ gen_helper_neon_abdl_u16,
+ gen_helper_neon_abdl_u32,
+ gen_helper_neon_abdl_u64,
+ NULL,
+ };
+ static NeonGenTwo64OpFn * const addfn[] = {
+ gen_helper_neon_addl_u16,
+ gen_helper_neon_addl_u32,
+ tcg_gen_add_i64,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], addfn[a->size]);
+}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 3fe39cd4f49..37fe9d46e0b 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5243,9 +5243,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{0, 0, 0, 7}, /* VSUBL: handled by decodetree */
{0, 0, 0, 7}, /* VSUBW: handled by decodetree */
{0, 0, 0, 7}, /* VADDHN: handled by decodetree */
- {0, 0, 0, 0}, /* VABAL */
+ {0, 0, 0, 7}, /* VABAL */
{0, 0, 0, 7}, /* VSUBHN: handled by decodetree */
- {0, 0, 0, 0}, /* VABDL */
+ {0, 0, 0, 7}, /* VABDL */
{0, 0, 0, 0}, /* VMLAL */
{0, 0, 0, 9}, /* VQDMLAL */
{0, 0, 0, 0}, /* VMLSL */
@@ -5306,31 +5306,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tmp2 = neon_load_reg(rm, pass);
}
switch (op) {
- case 5: case 7: /* VABAL, VABDL */
- switch ((size << 1) | u) {
- case 0:
- gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
- break;
- case 1:
- gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
- break;
- case 3:
- gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
- break;
- case 4:
- gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
- break;
- case 5:
- gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
- break;
- default: abort();
- }
- tcg_temp_free_i32(tmp2);
- tcg_temp_free_i32(tmp);
- break;
case 8: case 9: case 10: case 11: case 12: case 13:
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
@@ -5349,7 +5324,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case 10: /* VMLSL */
gen_neon_negl(cpu_V0, size);
/* Fall through */
- case 5: case 8: /* VABAL, VMLAL */
+ case 8: /* VABAL, VMLAL */
gen_neon_addl(size);
break;
case 9: case 11: /* VQDMLAL, VQDMLSL */
--
2.20.1
next prev parent reply other threads:[~2020-06-16 10:00 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-16 9:56 [PULL 00/23] target-arm queue Peter Maydell
2020-06-16 9:56 ` [PULL 01/23] target/arm: Fix missing temp frees in do_vshll_2sh Peter Maydell
2020-06-16 9:56 ` [PULL 02/23] target/arm: Convert Neon 3-reg-diff prewidening ops to decodetree Peter Maydell
2020-06-16 9:56 ` [PULL 03/23] target/arm: Convert Neon 3-reg-diff narrowing " Peter Maydell
2020-06-16 9:56 ` Peter Maydell [this message]
2020-06-16 9:56 ` [PULL 05/23] target/arm: Convert Neon 3-reg-diff long multiplies Peter Maydell
2020-06-16 9:56 ` [PULL 06/23] target/arm: Convert Neon 3-reg-diff saturating doubling multiplies Peter Maydell
2020-06-16 9:56 ` [PULL 07/23] target/arm: Convert Neon 3-reg-diff polynomial VMULL Peter Maydell
2020-06-16 9:56 ` [PULL 08/23] target/arm: Add 'static' and 'const' annotations to VSHLL function arrays Peter Maydell
2020-06-16 9:56 ` [PULL 09/23] target/arm: Add missing TCG temp free in do_2shift_env_64() Peter Maydell
2020-06-16 9:56 ` [PULL 10/23] target/arm: Convert Neon 2-reg-scalar integer multiplies to decodetree Peter Maydell
2020-06-16 9:56 ` [PULL 11/23] target/arm: Convert Neon 2-reg-scalar float " Peter Maydell
2020-06-16 9:56 ` [PULL 12/23] target/arm: Convert Neon 2-reg-scalar VQDMULH, VQRDMULH " Peter Maydell
2020-06-16 9:56 ` [PULL 13/23] target/arm: Convert Neon 2-reg-scalar VQRDMLAH, VQRDMLSH " Peter Maydell
2020-06-16 9:56 ` [PULL 14/23] target/arm: Convert Neon 2-reg-scalar long multiplies " Peter Maydell
2020-06-16 9:56 ` [PULL 15/23] target/arm: Convert Neon VEXT " Peter Maydell
2020-06-16 9:56 ` [PULL 16/23] target/arm: Convert Neon VTBL, VTBX " Peter Maydell
2020-06-16 9:56 ` [PULL 17/23] target/arm: Convert Neon VDUP (scalar) " Peter Maydell
2020-06-16 9:56 ` [PULL 18/23] hw/misc/imx6ul_ccm: Implement non writable bits in CCM registers Peter Maydell
2020-06-16 9:56 ` [PULL 19/23] Implement configurable descriptor size in ftgmac100 Peter Maydell
2020-06-16 9:56 ` [PULL 20/23] target/arm/cpu: adjust virtual time for all KVM arm cpus Peter Maydell
2020-06-16 9:57 ` [PULL 21/23] hw/net/imx_fec: Convert debug fprintf() to trace events Peter Maydell
2020-06-16 9:57 ` [PULL 22/23] sd: sdhci: Implement basic vendor specific register support Peter Maydell
2020-06-16 9:57 ` [PULL 23/23] hw: arm: Set vendor property for IMX SDHCI emulations Peter Maydell
2020-06-16 13:35 ` [PULL 00/23] target-arm queue Peter Maydell
2020-06-16 14:15 ` 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=20200616095702.25848-5-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).