mirror of https://github.com/xemu-project/xemu.git
target/arm: Convert Neon 2-reg-misc VSHLL to decodetree
Convert the VSHLL insn in the 2-reg-misc Neon group to decodetree. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200616170844.13318-6-peter.maydell@linaro.org
This commit is contained in:
parent
3882bdacb0
commit
749e2be36d
|
@ -459,6 +459,8 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
|
||||||
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
|
# 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_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
|
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
|
||||||
|
|
||||||
|
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
|
||||||
]
|
]
|
||||||
|
|
||||||
# Subgroup for size != 0b11
|
# Subgroup for size != 0b11
|
||||||
|
|
|
@ -3302,3 +3302,55 @@ DO_VMOVN(VMOVN, gen_neon_narrow_u)
|
||||||
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
|
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
|
||||||
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
|
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
|
||||||
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
|
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
|
||||||
|
|
||||||
|
static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
|
||||||
|
{
|
||||||
|
TCGv_i32 rm0, rm1;
|
||||||
|
TCGv_i64 rd;
|
||||||
|
static NeonGenWidenFn * const widenfns[] = {
|
||||||
|
gen_helper_neon_widen_u8,
|
||||||
|
gen_helper_neon_widen_u16,
|
||||||
|
tcg_gen_extu_i32_i64,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
NeonGenWidenFn *widenfn = widenfns[a->size];
|
||||||
|
|
||||||
|
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 & 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!widenfn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vfp_access_check(s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rd = tcg_temp_new_i64();
|
||||||
|
|
||||||
|
rm0 = neon_load_reg(a->vm, 0);
|
||||||
|
rm1 = neon_load_reg(a->vm, 1);
|
||||||
|
|
||||||
|
widenfn(rd, rm0);
|
||||||
|
tcg_gen_shli_i64(rd, rd, 8 << a->size);
|
||||||
|
neon_store_reg64(rd, a->vd);
|
||||||
|
widenfn(rd, rm1);
|
||||||
|
tcg_gen_shli_i64(rd, rd, 8 << a->size);
|
||||||
|
neon_store_reg64(rd, a->vd + 1);
|
||||||
|
|
||||||
|
tcg_temp_free_i64(rd);
|
||||||
|
tcg_temp_free_i32(rm0);
|
||||||
|
tcg_temp_free_i32(rm1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -2975,26 +2975,6 @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
|
||||||
tcg_temp_free_i32(rd);
|
tcg_temp_free_i32(rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
|
|
||||||
{
|
|
||||||
if (u) {
|
|
||||||
switch (size) {
|
|
||||||
case 0: gen_helper_neon_widen_u8(dest, src); break;
|
|
||||||
case 1: gen_helper_neon_widen_u16(dest, src); break;
|
|
||||||
case 2: tcg_gen_extu_i32_i64(dest, src); break;
|
|
||||||
default: abort();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (size) {
|
|
||||||
case 0: gen_helper_neon_widen_s8(dest, src); break;
|
|
||||||
case 1: gen_helper_neon_widen_s16(dest, src); break;
|
|
||||||
case 2: tcg_gen_ext_i32_i64(dest, src); break;
|
|
||||||
default: abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tcg_temp_free_i32(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
|
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
|
||||||
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
|
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
|
||||||
* table A7-13.
|
* table A7-13.
|
||||||
|
@ -4946,6 +4926,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||||
case NEON_2RM_VUZP:
|
case NEON_2RM_VUZP:
|
||||||
case NEON_2RM_VZIP:
|
case NEON_2RM_VZIP:
|
||||||
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
|
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
|
||||||
|
case NEON_2RM_VSHLL:
|
||||||
/* handled by decodetree */
|
/* handled by decodetree */
|
||||||
return 1;
|
return 1;
|
||||||
case NEON_2RM_VTRN:
|
case NEON_2RM_VTRN:
|
||||||
|
@ -4961,20 +4942,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||||
goto elementwise;
|
goto elementwise;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NEON_2RM_VSHLL:
|
|
||||||
if (q || (rd & 1)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
tmp = neon_load_reg(rm, 0);
|
|
||||||
tmp2 = neon_load_reg(rm, 1);
|
|
||||||
for (pass = 0; pass < 2; pass++) {
|
|
||||||
if (pass == 1)
|
|
||||||
tmp = tmp2;
|
|
||||||
gen_neon_widen(cpu_V0, tmp, size, 1);
|
|
||||||
tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
|
|
||||||
neon_store_reg64(cpu_V0, rd + pass);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NEON_2RM_VCVT_F16_F32:
|
case NEON_2RM_VCVT_F16_F32:
|
||||||
{
|
{
|
||||||
TCGv_ptr fpst;
|
TCGv_ptr fpst;
|
||||||
|
|
Loading…
Reference in New Issue