target/arm: Convert remaining simple 2-reg-misc Neon ops

Convert the remaining ops in the Neon 2-reg-misc group which
can be implemented simply with our do_2misc() helper.

Backports commit 84eae770af69c37a92496a4c4248875c070d5ee3 from qemu
This commit is contained in:
Peter Maydell 2021-02-25 12:50:51 -05:00 committed by Lioncash
parent 88f8111500
commit 4033a3ca5c
3 changed files with 86 additions and 31 deletions

View file

@ -456,6 +456,10 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1 AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1 AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
VCLS 1111 001 11 . 11 .. 00 .... 0 1000 . . 0 .... @2misc
VCLZ 1111 001 11 . 11 .. 00 .... 0 1001 . . 0 .... @2misc
VCNT 1111 001 11 . 11 .. 00 .... 0 1010 . . 0 .... @2misc
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
@ -472,6 +476,9 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
@ -489,6 +496,9 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0 VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0 VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
] ]
# Subgroup for size != 0b11 # Subgroup for size != 0b11

View file

@ -3648,3 +3648,72 @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a)
} }
return do_2misc(s, a, gen_rev16); return do_2misc(s, a, gen_rev16);
} }
static bool trans_VCLS(DisasContext *s, arg_2misc *a)
{
static NeonGenOneOpFn * const fn[] = {
gen_helper_neon_cls_s8,
gen_helper_neon_cls_s16,
gen_helper_neon_cls_s32,
NULL,
};
return do_2misc(s, a, fn[a->size]);
}
static void do_VCLZ_32(TCGContext *s, TCGv_i32 rd, TCGv_i32 rm)
{
tcg_gen_clzi_i32(s, rd, rm, 32);
}
static bool trans_VCLZ(DisasContext *s, arg_2misc *a)
{
static NeonGenOneOpFn * const fn[] = {
gen_helper_neon_clz_u8,
gen_helper_neon_clz_u16,
do_VCLZ_32,
NULL,
};
return do_2misc(s, a, fn[a->size]);
}
static bool trans_VCNT(DisasContext *s, arg_2misc *a)
{
if (a->size != 0) {
return false;
}
return do_2misc(s, a, gen_helper_neon_cnt_u8);
}
static bool trans_VABS_F(DisasContext *s, arg_2misc *a)
{
if (a->size != 2) {
return false;
}
/* TODO: FP16 : size == 1 */
return do_2misc(s, a, gen_helper_vfp_abss);
}
static bool trans_VNEG_F(DisasContext *s, arg_2misc *a)
{
if (a->size != 2) {
return false;
}
/* TODO: FP16 : size == 1 */
return do_2misc(s, a, gen_helper_vfp_negs);
}
static bool trans_VRECPE(DisasContext *s, arg_2misc *a)
{
if (a->size != 2) {
return false;
}
return do_2misc(s, a, gen_helper_recpe_u32);
}
static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
{
if (a->size != 2) {
return false;
}
return do_2misc(s, a, gen_helper_rsqrte_u32);
}

View file

@ -5040,6 +5040,13 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_2RM_SHA1SU1: case NEON_2RM_SHA1SU1:
case NEON_2RM_VREV32: case NEON_2RM_VREV32:
case NEON_2RM_VREV16: case NEON_2RM_VREV16:
case NEON_2RM_VCLS:
case NEON_2RM_VCLZ:
case NEON_2RM_VCNT:
case NEON_2RM_VABS_F:
case NEON_2RM_VNEG_F:
case NEON_2RM_VRECPE:
case NEON_2RM_VRSQRTE:
/* handled by decodetree */ /* handled by decodetree */
return 1; return 1;
case NEON_2RM_VTRN: case NEON_2RM_VTRN:
@ -5061,25 +5068,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
for (pass = 0; pass < (q ? 4 : 2); pass++) { for (pass = 0; pass < (q ? 4 : 2); pass++) {
tmp = neon_load_reg(s, rm, pass); tmp = neon_load_reg(s, rm, pass);
switch (op) { switch (op) {
case NEON_2RM_VCLS:
switch (size) {
case 0: gen_helper_neon_cls_s8(tcg_ctx, tmp, tmp); break;
case 1: gen_helper_neon_cls_s16(tcg_ctx, tmp, tmp); break;
case 2: gen_helper_neon_cls_s32(tcg_ctx, tmp, tmp); break;
default: abort();
}
break;
case NEON_2RM_VCLZ:
switch (size) {
case 0: gen_helper_neon_clz_u8(tcg_ctx, tmp, tmp); break;
case 1: gen_helper_neon_clz_u16(tcg_ctx, tmp, tmp); break;
case 2: tcg_gen_clzi_i32(tcg_ctx, tmp, tmp, 32); break;
default: abort();
}
break;
case NEON_2RM_VCNT:
gen_helper_neon_cnt_u8(tcg_ctx, tmp, tmp);
break;
case NEON_2RM_VQABS: case NEON_2RM_VQABS:
switch (size) { switch (size) {
case 0: case 0:
@ -5153,12 +5141,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tcg_temp_free_ptr(tcg_ctx, fpstatus); tcg_temp_free_ptr(tcg_ctx, fpstatus);
break; break;
} }
case NEON_2RM_VABS_F:
gen_helper_vfp_abss(tcg_ctx, tmp, tmp);
break;
case NEON_2RM_VNEG_F:
gen_helper_vfp_negs(tcg_ctx, tmp, tmp);
break;
case NEON_2RM_VSWP: case NEON_2RM_VSWP:
tmp2 = neon_load_reg(s, rd, pass); tmp2 = neon_load_reg(s, rd, pass);
neon_store_reg(s, rm, pass, tmp2); neon_store_reg(s, rm, pass, tmp2);
@ -5239,12 +5221,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tcg_temp_free_ptr(tcg_ctx, fpst); tcg_temp_free_ptr(tcg_ctx, fpst);
break; break;
} }
case NEON_2RM_VRECPE:
gen_helper_recpe_u32(tcg_ctx, tmp, tmp);
break;
case NEON_2RM_VRSQRTE:
gen_helper_rsqrte_u32(tcg_ctx, tmp, tmp);
break;
case NEON_2RM_VRECPE_F: case NEON_2RM_VRECPE_F:
{ {
TCGv_ptr fpstatus = get_fpstatus_ptr(tcg_ctx, 1); TCGv_ptr fpstatus = get_fpstatus_ptr(tcg_ctx, 1);