Commit 66432d6b authored by Peter Maydell's avatar Peter Maydell
Browse files

target/arm: Convert Neon VSHR 2-reg-shift insns to decodetree



Convert the VSHR 2-reg-shift insns to decodetree.

Note that unlike the legacy decoder, we present the right shift
amount to the trans_ function as a positive integer.

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20200522145520.6778-3-peter.maydell@linaro.org
parent d3c8c736
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -208,6 +208,21 @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
######################################################################
&2reg_shift vm vd q shift size

# Right shifts are encoded as N - shift, where N is the element size in bits.
%neon_rshift_i6  16:6 !function=rsub_64
%neon_rshift_i5  16:5 !function=rsub_32
%neon_rshift_i4  16:4 !function=rsub_16
%neon_rshift_i3  16:3 !function=rsub_8

@2reg_shr_d      .... ... . . . ......  .... .... 1 q:1 . . .... \
                 &2reg_shift vm=%vm_dp vd=%vd_dp size=3 shift=%neon_rshift_i6
@2reg_shr_s      .... ... . . . 1 ..... .... .... 0 q:1 . . .... \
                 &2reg_shift vm=%vm_dp vd=%vd_dp size=2 shift=%neon_rshift_i5
@2reg_shr_h      .... ... . . . 01 .... .... .... 0 q:1 . . .... \
                 &2reg_shift vm=%vm_dp vd=%vd_dp size=1 shift=%neon_rshift_i4
@2reg_shr_b      .... ... . . . 001 ... .... .... 0 q:1 . . .... \
                 &2reg_shift vm=%vm_dp vd=%vd_dp size=0 shift=%neon_rshift_i3

@2reg_shl_d      .... ... . . . shift:6      .... .... 1 q:1 . . .... \
                 &2reg_shift vm=%vm_dp vd=%vd_dp size=3
@2reg_shl_s      .... ... . . . 1 shift:5    .... .... 0 q:1 . . .... \
@@ -217,6 +232,16 @@ VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
@2reg_shl_b      .... ... . . . 001 shift:3  .... .... 0 q:1 . . .... \
                 &2reg_shift vm=%vm_dp vd=%vd_dp size=0

VSHR_S_2sh       1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
VSHR_S_2sh       1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
VSHR_S_2sh       1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
VSHR_S_2sh       1111 001 0 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b

VSHR_U_2sh       1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_d
VSHR_U_2sh       1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_s
VSHR_U_2sh       1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_h
VSHR_U_2sh       1111 001 1 1 . ...... .... 0000 . . . 1 .... @2reg_shr_b

VSHL_2sh         1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_d
VSHL_2sh         1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_s
VSHL_2sh         1111 001 0 1 . ...... .... 0101 . . . 1 .... @2reg_shl_h
+41 −0
Original line number Diff line number Diff line
@@ -31,6 +31,24 @@ static inline int plus1(DisasContext *s, int x)
    return x + 1;
}

static inline int rsub_64(DisasContext *s, int x)
{
    return 64 - x;
}

static inline int rsub_32(DisasContext *s, int x)
{
    return 32 - x;
}
static inline int rsub_16(DisasContext *s, int x)
{
    return 16 - x;
}
static inline int rsub_8(DisasContext *s, int x)
{
    return 8 - x;
}

/* Include the generated Neon decoder */
#include "decode-neon-dp.inc.c"
#include "decode-neon-ls.inc.c"
@@ -1240,3 +1258,26 @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)

DO_2SH(VSHL, tcg_gen_gvec_shli)
DO_2SH(VSLI, gen_gvec_sli)

static bool trans_VSHR_S_2sh(DisasContext *s, arg_2reg_shift *a)
{
    /* Signed shift out of range results in all-sign-bits */
    a->shift = MIN(a->shift, (8 << a->size) - 1);
    return do_vector_2sh(s, a, tcg_gen_gvec_sari);
}

static void gen_zero_rd_2sh(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
                            int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    tcg_gen_gvec_dup_imm(vece, rd_ofs, oprsz, maxsz, 0);
}

static bool trans_VSHR_U_2sh(DisasContext *s, arg_2reg_shift *a)
{
    /* Shift out of range is architecturally valid and results in zero. */
    if (a->shift >= (8 << a->size)) {
        return do_vector_2sh(s, a, gen_zero_rd_2sh);
    } else {
        return do_vector_2sh(s, a, tcg_gen_gvec_shri);
    }
}
+1 −20
Original line number Diff line number Diff line
@@ -5296,6 +5296,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
            op = (insn >> 8) & 0xf;

            switch (op) {
            case 0: /* VSHR */
            case 5: /* VSHL, VSLI */
                return 1; /* handled by decodetree */
            default:
@@ -5330,26 +5331,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
                }

                switch (op) {
                case 0:  /* VSHR */
                    /* Right shift comes here negative.  */
                    shift = -shift;
                    /* Shifts larger than the element size are architecturally
                     * valid.  Unsigned results in all zeros; signed results
                     * in all sign bits.
                     */
                    if (!u) {
                        tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
                                          MIN(shift, (8 << size) - 1),
                                          vec_size, vec_size);
                    } else if (shift >= 8 << size) {
                        tcg_gen_gvec_dup_imm(MO_8, rd_ofs, vec_size,
                                             vec_size, 0);
                    } else {
                        tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
                                          vec_size, vec_size);
                    }
                    return 0;

                case 1:  /* VSRA */
                    /* Right shift comes here negative.  */
                    shift = -shift;