summaryrefslogtreecommitdiff
path: root/target/arm/translate.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:25 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:25 +0100
commitb28be09570d0827969b62b8f82b0f720a9915427 (patch)
treef9e7883067c6f21e1fe8f40b10ee3736a10e698a /target/arm/translate.c
parent9593a3988c3e788790aa107d778386b09f456a6d (diff)
downloadqemu-b28be09570d0827969b62b8f82b0f720a9915427.zip
target/arm: Convert Neon 3-reg-diff prewidening ops to decodetree
Convert the "pre-widening" insns VADDL, VSUBL, VADDW and VSUBW in the Neon 3-registers-different-lengths group to decodetree. These insns work by widening one or both inputs to double their size, performing an add or subtract at the doubled size and then storing the double-size result. As usual, rather than copying the loop of the original decoder (which needs awkward code to avoid problems when source and destination registers overlap) we just unroll the two passes. 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.c16
1 files changed, 4 insertions, 12 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index bcdfec34d2..9376534441 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5241,7 +5241,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
/* Three registers of different lengths. */
int src1_wide;
int src2_wide;
- int prewiden;
/* undefreq: bit 0 : UNDEF if size == 0
* bit 1 : UNDEF if size == 1
* bit 2 : UNDEF if size == 2
@@ -5251,10 +5250,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
int undefreq;
/* prewiden, src1_wide, src2_wide, undefreq */
static const int neon_3reg_wide[16][4] = {
- {1, 0, 0, 0}, /* VADDL */
- {1, 1, 0, 0}, /* VADDW */
- {1, 0, 0, 0}, /* VSUBL */
- {1, 1, 0, 0}, /* VSUBW */
+ {0, 0, 0, 7}, /* VADDL: handled by decodetree */
+ {0, 0, 0, 7}, /* VADDW: handled by decodetree */
+ {0, 0, 0, 7}, /* VSUBL: handled by decodetree */
+ {0, 0, 0, 7}, /* VSUBW: handled by decodetree */
{0, 1, 1, 0}, /* VADDHN */
{0, 0, 0, 0}, /* VABAL */
{0, 1, 1, 0}, /* VSUBHN */
@@ -5269,7 +5268,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{0, 0, 0, 7}, /* Reserved: always UNDEF */
};
- prewiden = neon_3reg_wide[op][0];
src1_wide = neon_3reg_wide[op][1];
src2_wide = neon_3reg_wide[op][2];
undefreq = neon_3reg_wide[op][3];
@@ -5322,9 +5320,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
} else {
tmp = neon_load_reg(rn, pass);
}
- if (prewiden) {
- gen_neon_widen(cpu_V0, tmp, size, u);
- }
}
if (src2_wide) {
neon_load_reg64(cpu_V1, rm + pass);
@@ -5335,9 +5330,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
} else {
tmp2 = neon_load_reg(rm, pass);
}
- if (prewiden) {
- gen_neon_widen(cpu_V1, tmp2, size, u);
- }
}
switch (op) {
case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */