From 709610e606f04b2b5be96253fa489db1b265168b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Wed, 17 Jun 2020 00:43:16 -0400 Subject: [PATCH] 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.) Backports commit 9aaa23c2ae18e6fb9a291b81baf91341db76dfa0 from qemu --- qemu/target/arm/neon-dp.decode | 7 +++++++ qemu/target/arm/translate-neon.inc.c | 27 +++++++++++++++++++++++++++ qemu/target/arm/translate.c | 25 +------------------------ 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/qemu/target/arm/neon-dp.decode b/qemu/target/arm/neon-dp.decode index 91bc770d..6d890b21 100644 --- a/qemu/target/arm/neon-dp.decode +++ b/qemu/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/qemu/target/arm/translate-neon.inc.c b/qemu/target/arm/translate-neon.inc.c index 5bca9114..eb51fa98 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -2980,3 +2980,30 @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a) tcg_temp_free_i32(tcg_ctx, tmp); return true; } + +static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + 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(tcg_ctx, 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/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 5bf9beda..3fde781c 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -5688,31 +5688,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(tcg_ctx, 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; } }