From 681218b4abe9099d95744be49e258f75dcaa0ea0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 1 Mar 2021 17:47:23 -0500 Subject: [PATCH] target/arm: Implement fp16 for Neon VRINTX Convert the Neon VRINTX insn to use gvec, and use this to implement fp16 support for it. Backports 23afcdd2511f2a3dc05bed650d27bd25cf9b2a3c --- qemu/aarch64.h | 2 ++ qemu/aarch64eb.h | 2 ++ qemu/arm.h | 2 ++ qemu/armeb.h | 2 ++ qemu/header_gen.py | 2 ++ qemu/m68k.h | 2 ++ qemu/mips.h | 2 ++ qemu/mips64.h | 2 ++ qemu/mips64el.h | 2 ++ qemu/mipsel.h | 2 ++ qemu/powerpc.h | 2 ++ qemu/riscv32.h | 2 ++ qemu/riscv64.h | 2 ++ qemu/sparc.h | 2 ++ qemu/sparc64.h | 2 ++ qemu/target/arm/helper.h | 3 ++ qemu/target/arm/translate-neon.inc.c | 46 ++-------------------------- qemu/target/arm/vec_helper.c | 3 ++ qemu/x86_64.h | 2 ++ 19 files changed, 41 insertions(+), 43 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 79f72744..e369df0f 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_aarch64 #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_aarch64 #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_aarch64 +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_aarch64 +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 d26c4e31..9f9aec0c 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_aarch64eb #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_aarch64eb #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_aarch64eb +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_aarch64eb +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 3b858ce7..8580732e 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_arm #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_arm #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_arm +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_arm +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 0e8eb744..ef394fab 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_armeb #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_armeb #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_armeb +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_armeb +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 04a1717c..1845d682 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1856,6 +1856,8 @@ symbols = ( 'helper_gvec_vcvt_rm_uh', 'helper_gvec_vrint_rm_h', 'helper_gvec_vrint_rm_s', + 'helper_gvec_vrintx_h', + 'helper_gvec_vrintx_s', 'helper_power_down', 'helper_pre_hvc', 'helper_pre_smc', diff --git a/qemu/m68k.h b/qemu/m68k.h index db52d0aa..bc794c91 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_m68k #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_m68k #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_m68k +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_m68k +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 0aa1b397..e2cbb521 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_mips #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_mips #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_mips +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_mips +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 77794509..66439a9c 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_mips64 #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_mips64 #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_mips64 +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_mips64 +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 fdf05ba5..0a5d3f91 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_mips64el #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_mips64el #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_mips64el +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_mips64el +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 964851bf..cd673cb3 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_mipsel #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_mipsel #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_mipsel +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_mipsel +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 257edd51..8afd3500 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_powerpc #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_powerpc #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_powerpc +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_powerpc +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 c9636579..9a555282 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_riscv32 #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_riscv32 #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_riscv32 +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_riscv32 +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 7ff87883..92a8bb20 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_riscv64 #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_riscv64 #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_riscv64 +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_riscv64 +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 02803b3c..de57207f 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_sparc #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_sparc #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_sparc +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_sparc +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 e8ed1c21..f24591e1 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_sparc64 #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_sparc64 #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_sparc64 +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_sparc64 +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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 f2feb71e..891211cd 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -638,6 +638,9 @@ DEF_HELPER_FLAGS_4(gvec_vcvt_rm_uh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vrint_rm_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vrint_rm_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vrintx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vrintx_s, 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 15dbc902..992eb513 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -3729,48 +3729,6 @@ static bool trans_VQNEG(DisasContext *s, arg_2misc *a) return do_2misc(s, a, fn[a->size]); } -static bool do_2misc_fp(DisasContext *s, arg_2misc *a, - NeonGenOneSingleOpFn *fn) -{ - TCGContext *tcg_ctx = s->uc->tcg_ctx; - int pass; - TCGv_ptr fpst; - - /* Handle a 2-reg-misc operation by iterating 32 bits at a time */ - 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->size != 2) { - /* TODO: FP16 will be the size == 1 case */ - return false; - } - - if ((a->vd | a->vm) & a->q) { - return false; - } - - if (!vfp_access_check(s)) { - return true; - } - - fpst = fpstatus_ptr(tcg_ctx, FPST_STD); - for (pass = 0; pass < (a->q ? 4 : 2); pass++) { - TCGv_i32 tmp = neon_load_reg(s, a->vm, pass); - fn(tcg_ctx, tmp, tmp, fpst); - neon_store_reg(s, a->vd, pass, tmp); - } - tcg_temp_free_ptr(tcg_ctx, fpst); - - return true; -} - #define DO_2MISC_FP_VEC(INSN, HFUNC, SFUNC) \ static void gen_##INSN(TCGContext *s, unsigned vece, uint32_t rd_ofs, \ uint32_t rm_ofs, \ @@ -3809,12 +3767,14 @@ DO_2MISC_FP_VEC(VCVT_FU, gen_helper_gvec_ustoh, gen_helper_gvec_uitos) DO_2MISC_FP_VEC(VCVT_SF, gen_helper_gvec_tosszh, gen_helper_gvec_tosizs) DO_2MISC_FP_VEC(VCVT_UF, gen_helper_gvec_touszh, gen_helper_gvec_touizs) +DO_2MISC_FP_VEC(VRINTX_impl, gen_helper_gvec_vrintx_h, gen_helper_gvec_vrintx_s) + static bool trans_VRINTX(DisasContext *s, arg_2misc *a) { if (!arm_dc_feature(s, ARM_FEATURE_V8)) { return false; } - return do_2misc_fp(s, a, gen_helper_rints_exact); + return trans_VRINTX_impl(s, a); } #define DO_VEC_RMODE(INSN, RMODE, OP) \ diff --git a/qemu/target/arm/vec_helper.c b/qemu/target/arm/vec_helper.c index d82a5db2..4bb6ed65 100644 --- a/qemu/target/arm/vec_helper.c +++ b/qemu/target/arm/vec_helper.c @@ -751,6 +751,9 @@ DO_2OP(gvec_frsqrte_h, helper_rsqrte_f16, float16) DO_2OP(gvec_frsqrte_s, helper_rsqrte_f32, float32) DO_2OP(gvec_frsqrte_d, helper_rsqrte_f64, float64) +DO_2OP(gvec_vrintx_h, float16_round_to_int, float16) +DO_2OP(gvec_vrintx_s, float32_round_to_int, float32) + DO_2OP(gvec_sitos, helper_vfp_sitos, int32_t) DO_2OP(gvec_uitos, helper_vfp_uitos, uint32_t) DO_2OP(gvec_tosizs, helper_vfp_tosizs, float32) diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 51feda6d..6f16f384 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1850,6 +1850,8 @@ #define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_x86_64 #define helper_gvec_vrint_rm_h helper_gvec_vrint_rm_h_x86_64 #define helper_gvec_vrint_rm_s helper_gvec_vrint_rm_s_x86_64 +#define helper_gvec_vrintx_h helper_gvec_vrintx_h_x86_64 +#define helper_gvec_vrintx_s helper_gvec_vrintx_s_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