From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 06/23] target/arm: Convert Neon 3-reg-diff saturating doubling multiplies
Date: Tue, 16 Jun 2020 10:56:45 +0100 [thread overview]
Message-ID: <20200616095702.25848-7-peter.maydell@linaro.org> (raw)
In-Reply-To: <20200616095702.25848-1-peter.maydell@linaro.org>
Convert the Neon 3-reg-diff insns VQDMULL, VQDMLAL and VQDMLSL:
these are all saturating doubling long multiplies with a possible
accumulate step.
These are the last insns in the group which use the pass-over-each
elements loop, so we can delete that code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/neon-dp.decode | 6 +++
target/arm/translate-neon.inc.c | 82 +++++++++++++++++++++++++++++++++
target/arm/translate.c | 59 ++----------------------
3 files changed, 92 insertions(+), 55 deletions(-)
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
index 1da492df146..65ea30d3edf 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/neon-dp.decode
@@ -454,10 +454,16 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
VMLAL_S_3d 1111 001 0 1 . .. .... .... 1000 . 0 . 0 .... @3diff
VMLAL_U_3d 1111 001 1 1 . .. .... .... 1000 . 0 . 0 .... @3diff
+ VQDMLAL_3d 1111 001 0 1 . .. .... .... 1001 . 0 . 0 .... @3diff
+
VMLSL_S_3d 1111 001 0 1 . .. .... .... 1010 . 0 . 0 .... @3diff
VMLSL_U_3d 1111 001 1 1 . .. .... .... 1010 . 0 . 0 .... @3diff
+ VQDMLSL_3d 1111 001 0 1 . .. .... .... 1011 . 0 . 0 .... @3diff
+
VMULL_S_3d 1111 001 0 1 . .. .... .... 1100 . 0 . 0 .... @3diff
VMULL_U_3d 1111 001 1 1 . .. .... .... 1100 . 0 . 0 .... @3diff
+
+ VQDMULL_3d 1111 001 0 1 . .. .... .... 1101 . 0 . 0 .... @3diff
]
}
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
index c435f0685d4..083e3af8c56 100644
--- a/target/arm/translate-neon.inc.c
+++ b/target/arm/translate-neon.inc.c
@@ -2222,3 +2222,85 @@ DO_VMLAL(VMLAL_S,mull_s,add)
DO_VMLAL(VMLAL_U,mull_u,add)
DO_VMLAL(VMLSL_S,mull_s,sub)
DO_VMLAL(VMLSL_U,mull_u,sub)
+
+static void gen_VQDMULL_16(TCGv_i64 rd, TCGv_i32 rn, TCGv_i32 rm)
+{
+ gen_helper_neon_mull_s16(rd, rn, rm);
+ gen_helper_neon_addl_saturate_s32(rd, cpu_env, rd, rd);
+}
+
+static void gen_VQDMULL_32(TCGv_i64 rd, TCGv_i32 rn, TCGv_i32 rm)
+{
+ gen_mull_s32(rd, rn, rm);
+ gen_helper_neon_addl_saturate_s64(rd, cpu_env, rd, rd);
+}
+
+static bool trans_VQDMULL_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ NULL,
+ gen_VQDMULL_16,
+ gen_VQDMULL_32,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], NULL);
+}
+
+static void gen_VQDMLAL_acc_16(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ gen_helper_neon_addl_saturate_s32(rd, cpu_env, rn, rm);
+}
+
+static void gen_VQDMLAL_acc_32(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ gen_helper_neon_addl_saturate_s64(rd, cpu_env, rn, rm);
+}
+
+static bool trans_VQDMLAL_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ NULL,
+ gen_VQDMULL_16,
+ gen_VQDMULL_32,
+ NULL,
+ };
+ static NeonGenTwo64OpFn * const accfn[] = {
+ NULL,
+ gen_VQDMLAL_acc_16,
+ gen_VQDMLAL_acc_32,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], accfn[a->size]);
+}
+
+static void gen_VQDMLSL_acc_16(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ gen_helper_neon_negl_u32(rm, rm);
+ gen_helper_neon_addl_saturate_s32(rd, cpu_env, rn, rm);
+}
+
+static void gen_VQDMLSL_acc_32(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ tcg_gen_neg_i64(rm, rm);
+ gen_helper_neon_addl_saturate_s64(rd, cpu_env, rn, rm);
+}
+
+static bool trans_VQDMLSL_3d(DisasContext *s, arg_3diff *a)
+{
+ static NeonGenTwoOpWidenFn * const opfn[] = {
+ NULL,
+ gen_VQDMULL_16,
+ gen_VQDMULL_32,
+ NULL,
+ };
+ static NeonGenTwo64OpFn * const accfn[] = {
+ NULL,
+ gen_VQDMLSL_acc_16,
+ gen_VQDMLSL_acc_32,
+ NULL,
+ };
+
+ return do_long_3d(s, a, opfn[a->size], accfn[a->size]);
+}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index a2c47d19f21..88e91845c02 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5247,11 +5247,11 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{0, 0, 0, 7}, /* VSUBHN: handled by decodetree */
{0, 0, 0, 7}, /* VABDL */
{0, 0, 0, 7}, /* VMLAL */
- {0, 0, 0, 9}, /* VQDMLAL */
+ {0, 0, 0, 7}, /* VQDMLAL */
{0, 0, 0, 7}, /* VMLSL */
- {0, 0, 0, 9}, /* VQDMLSL */
+ {0, 0, 0, 7}, /* VQDMLSL */
{0, 0, 0, 7}, /* Integer VMULL */
- {0, 0, 0, 9}, /* VQDMULL */
+ {0, 0, 0, 7}, /* VQDMULL */
{0, 0, 0, 0xa}, /* Polynomial VMULL */
{0, 0, 0, 7}, /* Reserved: always UNDEF */
};
@@ -5282,58 +5282,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
}
return 0;
}
-
- /* Avoid overlapping operands. Wide source operands are
- always aligned so will never overlap with wide
- destinations in problematic ways. */
- if (rd == rm) {
- tmp = neon_load_reg(rm, 1);
- neon_store_scratch(2, tmp);
- } else if (rd == rn) {
- tmp = neon_load_reg(rn, 1);
- neon_store_scratch(2, tmp);
- }
- tmp3 = NULL;
- for (pass = 0; pass < 2; pass++) {
- if (pass == 1 && rd == rn) {
- tmp = neon_load_scratch(2);
- } else {
- tmp = neon_load_reg(rn, pass);
- }
- if (pass == 1 && rd == rm) {
- tmp2 = neon_load_scratch(2);
- } else {
- tmp2 = neon_load_reg(rm, pass);
- }
- switch (op) {
- case 9: case 11: case 13:
- /* VQDMLAL, VQDMLSL, VQDMULL */
- gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
- break;
- default: /* 15 is RESERVED: caught earlier */
- abort();
- }
- if (op == 13) {
- /* VQDMULL */
- gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- neon_store_reg64(cpu_V0, rd + pass);
- } else {
- /* Accumulate. */
- neon_load_reg64(cpu_V1, rd + pass);
- switch (op) {
- case 9: case 11: /* VQDMLAL, VQDMLSL */
- gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- if (op == 11) {
- gen_neon_negl(cpu_V0, size);
- }
- gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
- break;
- default:
- abort();
- }
- neon_store_reg64(cpu_V0, rd + pass);
- }
- }
+ abort(); /* all others handled by decodetree */
} else {
/* Two registers and a scalar. NB that for ops of this form
* the ARM ARM labels bit 24 as Q, but it is in our variable
--
2.20.1
next prev parent reply other threads:[~2020-06-16 10:05 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 ` [PULL 04/23] target/arm: Convert Neon 3-reg-diff VABAL, VABDL " Peter Maydell
2020-06-16 9:56 ` [PULL 05/23] target/arm: Convert Neon 3-reg-diff long multiplies Peter Maydell
2020-06-16 9:56 ` Peter Maydell [this message]
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-7-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).