From 4354448f57f0ddc04195180bbdad1358e64b4870 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 25 Feb 2021 12:27:31 -0500 Subject: [PATCH] target/arm: Convert vectorised 2-reg-misc Neon ops to decodetree Convert to decodetree the insns in the Neon 2-reg-misc grouping which we implement using gvec. Backports commit 75153179e9928775d5333243ea4b278f438d75ae from qemu --- qemu/target/arm/neon-dp.decode | 11 ++++++ qemu/target/arm/translate-neon.inc.c | 56 ++++++++++++++++++++++++++++ qemu/target/arm/translate.c | 35 ++++------------- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/qemu/target/arm/neon-dp.decode b/qemu/target/arm/neon-dp.decode index 8174f2f9..b5692070 100644 --- a/qemu/target/arm/neon-dp.decode +++ b/qemu/target/arm/neon-dp.decode @@ -447,9 +447,20 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc + VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc + VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc + VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc + VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc + VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc + VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc + VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc + + VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc + VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc + VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc diff --git a/qemu/target/arm/translate-neon.inc.c b/qemu/target/arm/translate-neon.inc.c index de5829c0..bba6f5c4 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -3494,3 +3494,59 @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a) return true; } + +static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + int vec_size = a->q ? 16 : 8; + int rd_ofs = neon_reg_offset(a->vd, 0); + int rm_ofs = neon_reg_offset(a->vm, 0); + + 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->size == 3) { + return false; + } + + if ((a->vd | a->vm) & a->q) { + return false; + } + + if (!vfp_access_check(s)) { + return true; + } + + fn(tcg_ctx, a->size, rd_ofs, rm_ofs, vec_size, vec_size); + + return true; +} + +#define DO_2MISC_VEC(INSN, FN) \ + static bool trans_##INSN(DisasContext *s, arg_2misc *a) \ + { \ + return do_2misc_vec(s, a, FN); \ + } + +DO_2MISC_VEC(VNEG, tcg_gen_gvec_neg) +DO_2MISC_VEC(VABS, tcg_gen_gvec_abs) +DO_2MISC_VEC(VCEQ0, gen_gvec_ceq0) +DO_2MISC_VEC(VCGT0, gen_gvec_cgt0) +DO_2MISC_VEC(VCLE0, gen_gvec_cle0) +DO_2MISC_VEC(VCGE0, gen_gvec_cge0) +DO_2MISC_VEC(VCLT0, gen_gvec_clt0) + +static bool trans_VMVN(DisasContext *s, arg_2misc *a) +{ + if (a->size != 0) { + return false; + } + return do_2misc_vec(s, a, tcg_gen_gvec_not); +} diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 89597ddc..4bbc966c 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -4964,7 +4964,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) int size; int pass; int u; - int vec_size; TCGv_i32 tmp, tmp2; if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { @@ -4988,7 +4987,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) VFP_DREG_D(rd, insn); VFP_DREG_M(rm, insn); size = (insn >> 20) & 3; - vec_size = q ? 16 : 8; rd_ofs = neon_reg_offset(rd, 0); rm_ofs = neon_reg_offset(rm, 0); @@ -5034,6 +5032,14 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) case NEON_2RM_VSHLL: case NEON_2RM_VCVT_F16_F32: case NEON_2RM_VCVT_F32_F16: + case NEON_2RM_VMVN: + case NEON_2RM_VNEG: + case NEON_2RM_VABS: + case NEON_2RM_VCEQ0: + case NEON_2RM_VCGT0: + case NEON_2RM_VCLE0: + case NEON_2RM_VCGE0: + case NEON_2RM_VCLT0: /* handled by decodetree */ return 1; case NEON_2RM_VTRN: @@ -5095,31 +5101,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) q ? gen_helper_crypto_sha256su0 : gen_helper_crypto_sha1su1); break; - case NEON_2RM_VMVN: - tcg_gen_gvec_not(tcg_ctx, 0, rd_ofs, rm_ofs, vec_size, vec_size); - break; - case NEON_2RM_VNEG: - tcg_gen_gvec_neg(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; - case NEON_2RM_VABS: - tcg_gen_gvec_abs(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; - - case NEON_2RM_VCEQ0: - gen_gvec_ceq0(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; - case NEON_2RM_VCGT0: - gen_gvec_cgt0(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; - case NEON_2RM_VCLE0: - gen_gvec_cle0(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; - case NEON_2RM_VCGE0: - gen_gvec_cge0(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; - case NEON_2RM_VCLT0: - gen_gvec_clt0(tcg_ctx, size, rd_ofs, rm_ofs, vec_size, vec_size); - break; default: elementwise: