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: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
54e96c744b
commit
9aaa23c2ae
@ -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 .... \
|
VTBL 1111 001 1 1 . 11 .... .... 10 len:2 . op:1 . 0 .... \
|
||||||
vm=%vm_dp vn=%vn_dp vd=%vd_dp
|
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
|
# Subgroup for size != 0b11
|
||||||
|
@ -2944,3 +2944,29 @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
|
|||||||
tcg_temp_free_i32(tmp);
|
tcg_temp_free_i32(tmp);
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
@ -5574,31 +5574,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
|||||||
}
|
}
|
||||||
break;
|
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 {
|
} else {
|
||||||
|
/* VTBL, VTBX, VDUP: handled by decodetree */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user