Skip to content

Commit

Permalink
target/arm: Convert Neon narrowing moves to decodetree
Browse files Browse the repository at this point in the history
Convert the Neon narrowing moves VMQNV, VQMOVN, VQMOVUN in the 2-reg-misc
group to decodetree.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200616170844.13318-5-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Jun 23, 2020
1 parent 567663a commit 3882bda
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 79 deletions.
9 changes: 9 additions & 0 deletions target/arm/neon-dp.decode
Expand Up @@ -439,6 +439,8 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm

@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
&2misc vm=%vm_dp vd=%vd_dp
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
&2misc vm=%vm_dp vd=%vd_dp q=0

VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc

Expand All @@ -450,6 +452,13 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm

VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc

VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
# VQMOVUN: unsigned result (source is always signed)
VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
]

# Subgroup for size != 0b11
Expand Down
59 changes: 59 additions & 0 deletions target/arm/translate-neon.inc.c
Expand Up @@ -3243,3 +3243,62 @@ static bool trans_VZIP(DisasContext *s, arg_2misc *a)
};
return do_zip_uzp(s, a, fn[a->q][a->size]);
}

static bool do_vmovn(DisasContext *s, arg_2misc *a,
NeonGenNarrowEnvFn *narrowfn)
{
TCGv_i64 rm;
TCGv_i32 rd0, rd1;

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->vm & 1) {
return false;
}

if (!narrowfn) {
return false;
}

if (!vfp_access_check(s)) {
return true;
}

rm = tcg_temp_new_i64();
rd0 = tcg_temp_new_i32();
rd1 = tcg_temp_new_i32();

neon_load_reg64(rm, a->vm);
narrowfn(rd0, cpu_env, rm);
neon_load_reg64(rm, a->vm + 1);
narrowfn(rd1, cpu_env, rm);
neon_store_reg(a->vd, 0, rd0);
neon_store_reg(a->vd, 1, rd1);
tcg_temp_free_i64(rm);
return true;
}

#define DO_VMOVN(INSN, FUNC) \
static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
{ \
static NeonGenNarrowEnvFn * const narrowfn[] = { \
FUNC##8, \
FUNC##16, \
FUNC##32, \
NULL, \
}; \
return do_vmovn(s, a, narrowfn[a->size]); \
}

DO_VMOVN(VMOVN, gen_neon_narrow_u)
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
81 changes: 2 additions & 79 deletions target/arm/translate.c
Expand Up @@ -2975,46 +2975,6 @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
tcg_temp_free_i32(rd);
}

static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_narrow_u8(dest, src); break;
case 1: gen_helper_neon_narrow_u16(dest, src); break;
case 2: tcg_gen_extrl_i64_i32(dest, src); break;
default: abort();
}
}

static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
default: abort();
}
}

static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
default: abort();
}
}

static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
default: abort();
}
}

static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
{
if (u) {
Expand All @@ -3035,24 +2995,6 @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
tcg_temp_free_i32(src);
}

static void gen_neon_narrow_op(int op, int u, int size,
TCGv_i32 dest, TCGv_i64 src)
{
if (op) {
if (u) {
gen_neon_unarrow_sats(size, dest, src);
} else {
gen_neon_narrow(size, dest, src);
}
} else {
if (u) {
gen_neon_narrow_satu(size, dest, src);
} else {
gen_neon_narrow_sats(size, dest, src);
}
}
}

/* Symbolic constants for op fields for Neon 2-register miscellaneous.
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
* table A7-13.
Expand Down Expand Up @@ -4994,8 +4936,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
!arm_dc_feature(s, ARM_FEATURE_V8)) {
return 1;
}
if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
q && ((rm | rd) & 1)) {
if (q && ((rm | rd) & 1)) {
return 1;
}
switch (op) {
Expand All @@ -5004,6 +4945,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
case NEON_2RM_VUZP:
case NEON_2RM_VZIP:
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
/* handled by decodetree */
return 1;
case NEON_2RM_VTRN:
Expand All @@ -5019,25 +4961,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
goto elementwise;
}
break;
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
/* also VQMOVUN; op field and mnemonics don't line up */
if (rm & 1) {
return 1;
}
tmp2 = NULL;
for (pass = 0; pass < 2; pass++) {
neon_load_reg64(cpu_V0, rm + pass);
tmp = tcg_temp_new_i32();
gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
tmp, cpu_V0);
if (pass == 0) {
tmp2 = tmp;
} else {
neon_store_reg(rd, 0, tmp2);
neon_store_reg(rd, 1, tmp);
}
}
break;
case NEON_2RM_VSHLL:
if (q || (rd & 1)) {
return 1;
Expand Down

0 comments on commit 3882bda

Please sign in to comment.