aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:26 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:26 +0100
commit3a1d9eb07b767a7592abca642af80906f9eab0ed (patch)
treed68710be71cc3d847cff2111a126a3a42f4d6c7a /target/arm/translate.c
parentf5b28401200ec95ba89552df3ecdcdc342f6b90b (diff)
downloadqemu-3a1d9eb07b767a7592abca642af80906f9eab0ed.zip
qemu-3a1d9eb07b767a7592abca642af80906f9eab0ed.tar.gz
qemu-3a1d9eb07b767a7592abca642af80906f9eab0ed.tar.bz2
target/arm: Convert Neon 3-reg-diff long multiplies
Convert the Neon 3-reg-diff insns VMULL, VMLAL and VMLSL; these perform a 32x32->64 multiply with possible accumulate. Note that for VMLSL we do the accumulate directly with a subtraction rather than doing a negate-then-add as the old code did. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r--target/arm/translate.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 37fe9d4..a2c47d1 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5246,11 +5246,11 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{0, 0, 0, 7}, /* VABAL */
{0, 0, 0, 7}, /* VSUBHN: handled by decodetree */
{0, 0, 0, 7}, /* VABDL */
- {0, 0, 0, 0}, /* VMLAL */
+ {0, 0, 0, 7}, /* VMLAL */
{0, 0, 0, 9}, /* VQDMLAL */
- {0, 0, 0, 0}, /* VMLSL */
+ {0, 0, 0, 7}, /* VMLSL */
{0, 0, 0, 9}, /* VQDMLSL */
- {0, 0, 0, 0}, /* Integer VMULL */
+ {0, 0, 0, 7}, /* Integer VMULL */
{0, 0, 0, 9}, /* VQDMULL */
{0, 0, 0, 0xa}, /* Polynomial VMULL */
{0, 0, 0, 7}, /* Reserved: always UNDEF */
@@ -5306,8 +5306,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tmp2 = neon_load_reg(rm, pass);
}
switch (op) {
- case 8: case 9: case 10: case 11: case 12: case 13:
- /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
+ 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 */
@@ -5317,16 +5317,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
/* VQDMULL */
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
neon_store_reg64(cpu_V0, rd + pass);
- } else if (op == 5 || (op >= 8 && op <= 11)) {
+ } else {
/* Accumulate. */
neon_load_reg64(cpu_V1, rd + pass);
switch (op) {
- case 10: /* VMLSL */
- gen_neon_negl(cpu_V0, size);
- /* Fall through */
- case 8: /* VABAL, VMLAL */
- gen_neon_addl(size);
- break;
case 9: case 11: /* VQDMLAL, VQDMLSL */
gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
if (op == 11) {
@@ -5338,9 +5332,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
abort();
}
neon_store_reg64(cpu_V0, rd + pass);
- } else {
- /* Write back the result. */
- neon_store_reg64(cpu_V0, rd + pass);
}
}
} else {