summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Maydell2020-06-16 11:32:28 +0200
committerPeter Maydell2020-06-16 11:32:28 +0200
commit9aaa23c2ae18e6fb9a291b81baf91341db76dfa0 (patch)
tree7482699ac999a191de68fb6b3d61d26e11c6b35c
parenttarget/arm: Convert Neon VTBL, VTBX to decodetree (diff)
downloadqemu-9aaa23c2ae18e6fb9a291b81baf91341db76dfa0.tar.gz
qemu-9aaa23c2ae18e6fb9a291b81baf91341db76dfa0.tar.xz
qemu-9aaa23c2ae18e6fb9a291b81baf91341db76dfa0.zip
target/arm: Convert Neon VDUP (scalar) to decodetree
Convert the Neon VDUP (scalar) insn to decodetree. (Note that we can't call this just "VDUP" as we used that already in vfp.decode for the "VDUP (general purpose register" insn.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--target/arm/neon-dp.decode7
-rw-r--r--target/arm/translate-neon.inc.c26
-rw-r--r--target/arm/translate.c25
3 files changed, 34 insertions, 24 deletions
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
index 91bc770dfb..6d890b2161 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/neon-dp.decode
@@ -422,6 +422,13 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
VTBL 1111 001 1 1 . 11 .... .... 10 len:2 . op:1 . 0 .... \
vm=%vm_dp vn=%vn_dp vd=%vd_dp
+
+ VDUP_scalar 1111 001 1 1 . 11 index:3 1 .... 11 000 q:1 . 0 .... \
+ vm=%vm_dp vd=%vd_dp size=0
+ VDUP_scalar 1111 001 1 1 . 11 index:2 10 .... 11 000 q:1 . 0 .... \
+ vm=%vm_dp vd=%vd_dp size=1
+ VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
+ vm=%vm_dp vd=%vd_dp size=2
]
# Subgroup for size != 0b11
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
index da0e5dbc6f..a5aa56bbde 100644
--- a/target/arm/translate-neon.inc.c
+++ b/target/arm/translate-neon.inc.c
@@ -2944,3 +2944,29 @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
tcg_temp_free_i32(tmp);
return true;
}
+
+static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
+{
+ 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->vm) & 0x10)) {
+ return false;
+ }
+
+ if (a->vd & a->q) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
+ neon_element_offset(a->vm, a->index, a->size),
+ a->q ? 16 : 8, a->q ? 16 : 8);
+ return true;
+}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 0c6425928f..6d18892ade 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5574,31 +5574,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
}
break;
}
- } else if ((insn & (1 << 10)) == 0) {
- /* VTBL, VTBX: handled by decodetree */
- return 1;
- } else if ((insn & 0x380) == 0) {
- /* VDUP */
- int element;
- MemOp size;
-
- if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
- return 1;
- }
- if (insn & (1 << 16)) {
- size = MO_8;
- element = (insn >> 17) & 7;
- } else if (insn & (1 << 17)) {
- size = MO_16;
- element = (insn >> 18) & 3;
- } else {
- size = MO_32;
- element = (insn >> 19) & 1;
- }
- tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
- neon_element_offset(rm, element, size),
- q ? 16 : 8, q ? 16 : 8);
} else {
+ /* VTBL, VTBX, VDUP: handled by decodetree */
return 1;
}
}