From 4033a3ca5c35806b69c842e359f10c46f3dcc15e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 25 Feb 2021 12:50:51 -0500 Subject: [PATCH] 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 --- qemu/target/arm/neon-dp.decode | 10 ++++ qemu/target/arm/translate-neon.inc.c | 69 ++++++++++++++++++++++++++++ qemu/target/arm/translate.c | 38 +++------------ 3 files changed, 86 insertions(+), 31 deletions(-) diff --git a/qemu/target/arm/neon-dp.decode b/qemu/target/arm/neon-dp.decode index 0a791af4..f947f7d0 100644 --- a/qemu/target/arm/neon-dp.decode +++ b/qemu/target/arm/neon-dp.decode @@ -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 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 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 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 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_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 diff --git a/qemu/target/arm/translate-neon.inc.c b/qemu/target/arm/translate-neon.inc.c index 0543584e..33a17da9 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -3648,3 +3648,72 @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a) } 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); +} diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 4e0b72f8..6c3bc534 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -5040,6 +5040,13 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) case NEON_2RM_SHA1SU1: case NEON_2RM_VREV32: 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 */ return 1; 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++) { tmp = neon_load_reg(s, rm, pass); 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: switch (size) { case 0: @@ -5153,12 +5141,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) tcg_temp_free_ptr(tcg_ctx, fpstatus); 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: tmp2 = neon_load_reg(s, rd, pass); 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); 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: { TCGv_ptr fpstatus = get_fpstatus_ptr(tcg_ctx, 1);