Commit 9aaa23c2 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent 54e96c74
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
+26 −0
Original line number Diff line number Diff line
@@ -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;
}
+1 −24
Original line number Diff line number Diff line
@@ -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;
            }
        }