From 948b01ad014c492f420b08ded814de56afe416a9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 1 Mar 2021 17:33:18 -0500 Subject: [PATCH] target/arm: Convert Neon VCVT fixed-point to gvec Convert the Neon VCVT float<->fixed-point insns to a gvec style, in preparation for adding fp16 support. Backports 7b959c5890deb9a6d71bc6800006a0eae0a84c60 --- qemu/aarch64.h | 4 ++++ qemu/aarch64eb.h | 4 ++++ qemu/arm.h | 4 ++++ qemu/armeb.h | 4 ++++ qemu/header_gen.py | 4 ++++ qemu/m68k.h | 4 ++++ qemu/mips.h | 4 ++++ qemu/mips64.h | 4 ++++ qemu/mips64el.h | 4 ++++ qemu/mipsel.h | 4 ++++ qemu/powerpc.h | 4 ++++ qemu/riscv32.h | 4 ++++ qemu/riscv64.h | 4 ++++ qemu/sparc.h | 4 ++++ qemu/sparc64.h | 4 ++++ qemu/target/arm/helper.h | 5 ++++ qemu/target/arm/translate-neon.inc.c | 35 ++++++++++++++-------------- qemu/target/arm/vec_helper.c | 20 ++++++++++++++++ qemu/x86_64.h | 4 ++++ 19 files changed, 107 insertions(+), 17 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 67f5efe2..254c94e8 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_aarch64 #define helper_gvec_touszh helper_gvec_touszh_aarch64 #define helper_gvec_touizs helper_gvec_touizs_aarch64 +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_aarch64 +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_aarch64 +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_aarch64 +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_aarch64 #define helper_power_down helper_power_down_aarch64 #define helper_pre_hvc helper_pre_hvc_aarch64 #define helper_pre_smc helper_pre_smc_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 63695040..71f495d8 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_aarch64eb #define helper_gvec_touszh helper_gvec_touszh_aarch64eb #define helper_gvec_touizs helper_gvec_touizs_aarch64eb +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_aarch64eb +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_aarch64eb +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_aarch64eb +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_aarch64eb #define helper_power_down helper_power_down_aarch64eb #define helper_pre_hvc helper_pre_hvc_aarch64eb #define helper_pre_smc helper_pre_smc_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 0e4ec7d1..2471b7ba 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_arm #define helper_gvec_touszh helper_gvec_touszh_arm #define helper_gvec_touizs helper_gvec_touizs_arm +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_arm +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_arm +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_arm +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_arm #define helper_power_down helper_power_down_arm #define helper_pre_hvc helper_pre_hvc_arm #define helper_pre_smc helper_pre_smc_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index e5723635..6be6fb58 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_armeb #define helper_gvec_touszh helper_gvec_touszh_armeb #define helper_gvec_touizs helper_gvec_touizs_armeb +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_armeb +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_armeb +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_armeb +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_armeb #define helper_power_down helper_power_down_armeb #define helper_pre_hvc helper_pre_hvc_armeb #define helper_pre_smc helper_pre_smc_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 46e4b689..dd8cb5a9 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1842,6 +1842,10 @@ symbols = ( 'helper_gvec_tosizs', 'helper_gvec_touszh', 'helper_gvec_touizs', + 'helper_gvec_vcvt_sf', + 'helper_gvec_vcvt_uf', + 'helper_gvec_vcvt_fs', + 'helper_gvec_vcvt_fu', 'helper_power_down', 'helper_pre_hvc', 'helper_pre_smc', diff --git a/qemu/m68k.h b/qemu/m68k.h index d436f9e8..27ca362d 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_m68k #define helper_gvec_touszh helper_gvec_touszh_m68k #define helper_gvec_touizs helper_gvec_touizs_m68k +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_m68k +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_m68k +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_m68k +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_m68k #define helper_power_down helper_power_down_m68k #define helper_pre_hvc helper_pre_hvc_m68k #define helper_pre_smc helper_pre_smc_m68k diff --git a/qemu/mips.h b/qemu/mips.h index e4114b09..8b44bdfb 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_mips #define helper_gvec_touszh helper_gvec_touszh_mips #define helper_gvec_touizs helper_gvec_touizs_mips +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_mips +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_mips +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_mips +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_mips #define helper_power_down helper_power_down_mips #define helper_pre_hvc helper_pre_hvc_mips #define helper_pre_smc helper_pre_smc_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 95e0ce6b..03513957 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_mips64 #define helper_gvec_touszh helper_gvec_touszh_mips64 #define helper_gvec_touizs helper_gvec_touizs_mips64 +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_mips64 +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_mips64 +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_mips64 +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_mips64 #define helper_power_down helper_power_down_mips64 #define helper_pre_hvc helper_pre_hvc_mips64 #define helper_pre_smc helper_pre_smc_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index bd4166c6..db3a4f2c 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_mips64el #define helper_gvec_touszh helper_gvec_touszh_mips64el #define helper_gvec_touizs helper_gvec_touizs_mips64el +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_mips64el +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_mips64el +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_mips64el +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_mips64el #define helper_power_down helper_power_down_mips64el #define helper_pre_hvc helper_pre_hvc_mips64el #define helper_pre_smc helper_pre_smc_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 0303a93d..4fbec7ea 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_mipsel #define helper_gvec_touszh helper_gvec_touszh_mipsel #define helper_gvec_touizs helper_gvec_touizs_mipsel +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_mipsel +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_mipsel +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_mipsel +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_mipsel #define helper_power_down helper_power_down_mipsel #define helper_pre_hvc helper_pre_hvc_mipsel #define helper_pre_smc helper_pre_smc_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 781c0c8e..dea9a272 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_powerpc #define helper_gvec_touszh helper_gvec_touszh_powerpc #define helper_gvec_touizs helper_gvec_touizs_powerpc +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_powerpc +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_powerpc +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_powerpc +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_powerpc #define helper_power_down helper_power_down_powerpc #define helper_pre_hvc helper_pre_hvc_powerpc #define helper_pre_smc helper_pre_smc_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 4f289ebd..acaa31b6 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_riscv32 #define helper_gvec_touszh helper_gvec_touszh_riscv32 #define helper_gvec_touizs helper_gvec_touizs_riscv32 +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_riscv32 +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_riscv32 +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_riscv32 +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_riscv32 #define helper_power_down helper_power_down_riscv32 #define helper_pre_hvc helper_pre_hvc_riscv32 #define helper_pre_smc helper_pre_smc_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 2d965fbd..29e9ca3f 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_riscv64 #define helper_gvec_touszh helper_gvec_touszh_riscv64 #define helper_gvec_touizs helper_gvec_touizs_riscv64 +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_riscv64 +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_riscv64 +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_riscv64 +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_riscv64 #define helper_power_down helper_power_down_riscv64 #define helper_pre_hvc helper_pre_hvc_riscv64 #define helper_pre_smc helper_pre_smc_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index c149d4a3..a9e97a6a 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_sparc #define helper_gvec_touszh helper_gvec_touszh_sparc #define helper_gvec_touizs helper_gvec_touizs_sparc +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_sparc +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_sparc +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_sparc +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_sparc #define helper_power_down helper_power_down_sparc #define helper_pre_hvc helper_pre_hvc_sparc #define helper_pre_smc helper_pre_smc_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 842b4f4e..1dbb5e80 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_sparc64 #define helper_gvec_touszh helper_gvec_touszh_sparc64 #define helper_gvec_touizs helper_gvec_touizs_sparc64 +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_sparc64 +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_sparc64 +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_sparc64 +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_sparc64 #define helper_power_down helper_power_down_sparc64 #define helper_pre_hvc helper_pre_hvc_sparc64 #define helper_pre_smc helper_pre_smc_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index b93a3f5f..c2808810 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -621,6 +621,11 @@ DEF_HELPER_FLAGS_4(gvec_tosizs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_touszh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_touizs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_sf, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_uf, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_fs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_fu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_4(gvec_frecpe_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_frecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_frecpe_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) diff --git a/qemu/target/arm/translate-neon.inc.c b/qemu/target/arm/translate-neon.inc.c index f0dee6d1..4d3ff4e4 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -1634,18 +1634,25 @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a) } static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, - NeonGenTwoSingleOpFn *fn) + gen_helper_gvec_2_ptr *fn) { /* FP operations in 2-reg-and-shift group */ TCGContext *tcg_ctx = s->uc->tcg_ctx; - TCGv_i32 tmp, shiftv; - TCGv_ptr fpstatus; - int pass; + int vec_size = a->q ? 16 : 8; + int rd_ofs = neon_reg_offset(a->vd, 0); + int rm_ofs = neon_reg_offset(a->vm, 0); + TCGv_ptr fpst; if (!arm_dc_feature(s, ARM_FEATURE_NEON)) { return false; } + if (a->size != 0) { + if (!dc_isar_feature(aa32_fp16_arith, s)) { + 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)) { @@ -1660,15 +1667,9 @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, return true; } - fpstatus = fpstatus_ptr(tcg_ctx, FPST_STD); - shiftv = tcg_const_i32(tcg_ctx, a->shift); - for (pass = 0; pass < (a->q ? 4 : 2); pass++) { - tmp = neon_load_reg(s, a->vm, pass); - fn(tcg_ctx, tmp, tmp, shiftv, fpstatus); - neon_store_reg(s, a->vd, pass, tmp); - } - tcg_temp_free_ptr(tcg_ctx, fpstatus); - tcg_temp_free_i32(tcg_ctx, shiftv); + fpst = fpstatus_ptr(tcg_ctx, a->size ? FPST_STD_F16 : FPST_STD); + tcg_gen_gvec_2_ptr(tcg_ctx, rd_ofs, rm_ofs, fpst, vec_size, vec_size, a->shift, fn); + tcg_temp_free_ptr(tcg_ctx, fpst); return true; } @@ -1678,10 +1679,10 @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, return do_fp_2sh(s, a, FUNC); \ } -DO_FP_2SH(VCVT_SF, gen_helper_vfp_sltos) -DO_FP_2SH(VCVT_UF, gen_helper_vfp_ultos) -DO_FP_2SH(VCVT_FS, gen_helper_vfp_tosls_round_to_zero) -DO_FP_2SH(VCVT_FU, gen_helper_vfp_touls_round_to_zero) +DO_FP_2SH(VCVT_SF, gen_helper_gvec_vcvt_sf) +DO_FP_2SH(VCVT_UF, gen_helper_gvec_vcvt_uf) +DO_FP_2SH(VCVT_FS, gen_helper_gvec_vcvt_fs) +DO_FP_2SH(VCVT_FU, gen_helper_gvec_vcvt_fu) static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op) { diff --git a/qemu/target/arm/vec_helper.c b/qemu/target/arm/vec_helper.c index 36763645..b411c5e2 100644 --- a/qemu/target/arm/vec_helper.c +++ b/qemu/target/arm/vec_helper.c @@ -1845,3 +1845,23 @@ DO_NEON_PAIRWISE(neon_pmax, max) DO_NEON_PAIRWISE(neon_pmin, min) #undef DO_NEON_PAIRWISE + +#define DO_VCVT_FIXED(NAME, FUNC, TYPE) \ + void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \ + { \ + intptr_t i, oprsz = simd_oprsz(desc); \ + int shift = simd_data(desc); \ + TYPE *d = vd, *n = vn; \ + float_status *fpst = stat; \ + for (i = 0; i < oprsz / sizeof(TYPE); i++) { \ + d[i] = FUNC(n[i], shift, fpst); \ + } \ + clear_tail(d, oprsz, simd_maxsz(desc)); \ + } + +DO_VCVT_FIXED(gvec_vcvt_sf, helper_vfp_sltos, uint32_t) +DO_VCVT_FIXED(gvec_vcvt_uf, helper_vfp_ultos, uint32_t) +DO_VCVT_FIXED(gvec_vcvt_fs, helper_vfp_tosls_round_to_zero, uint32_t) +DO_VCVT_FIXED(gvec_vcvt_fu, helper_vfp_touls_round_to_zero, uint32_t) + +#undef DO_VCVT_FIXED diff --git a/qemu/x86_64.h b/qemu/x86_64.h index a3ab1eef..d941646a 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1836,6 +1836,10 @@ #define helper_gvec_tosizs helper_gvec_tosizs_x86_64 #define helper_gvec_touszh helper_gvec_touszh_x86_64 #define helper_gvec_touizs helper_gvec_touizs_x86_64 +#define helper_gvec_vcvt_sf helper_gvec_vcvt_sf_x86_64 +#define helper_gvec_vcvt_uf helper_gvec_vcvt_uf_x86_64 +#define helper_gvec_vcvt_fs helper_gvec_vcvt_fs_x86_64 +#define helper_gvec_vcvt_fu helper_gvec_vcvt_fu_x86_64 #define helper_power_down helper_power_down_x86_64 #define helper_pre_hvc helper_pre_hvc_x86_64 #define helper_pre_smc helper_pre_smc_x86_64