From eb4054d04f699c755dc070575ca000c31a9d4751 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 1 Mar 2021 17:40:34 -0500 Subject: [PATCH] target/arm: Implement fp16 for Neon VCVT with rounding modes Convert the Neon VCVT with-specified-rounding-mode instructions to gvec, and use this to implement fp16 support for them. Backports ca88a6efdf4ce96b646a896059f9bd324c2cebc4 --- 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 | 106 ++++++++++----------------- qemu/target/arm/vec_helper.c | 23 ++++++ qemu/x86_64.h | 4 + 19 files changed, 130 insertions(+), 68 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 1d964a98..19eff986 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_aarch64 #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_aarch64 #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_aarch64 +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_aarch64 +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_aarch64 +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_aarch64 +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 5a1929e1..78eab736 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_aarch64eb #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_aarch64eb #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_aarch64eb +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_aarch64eb +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_aarch64eb +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_aarch64eb +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 7b32f089..01e01b35 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_arm #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_arm #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_arm +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_arm +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_arm +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_arm +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 2eb31bc2..663e4945 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_armeb #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_armeb #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_armeb +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_armeb +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_armeb +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_armeb +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 cfec3f64..a9412d54 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1850,6 +1850,10 @@ symbols = ( 'helper_gvec_vcvt_uh', 'helper_gvec_vcvt_hs', 'helper_gvec_vcvt_hu', + 'helper_gvec_vcvt_rm_ss', + 'helper_gvec_vcvt_rm_us', + 'helper_gvec_vcvt_rm_sh', + 'helper_gvec_vcvt_rm_uh', 'helper_power_down', 'helper_pre_hvc', 'helper_pre_smc', diff --git a/qemu/m68k.h b/qemu/m68k.h index 20721a59..b424f5af 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_m68k #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_m68k #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_m68k +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_m68k +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_m68k +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_m68k +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 fb114f1a..8706d454 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_mips #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_mips #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_mips +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_mips +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_mips +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_mips +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 87c1f191..4ad3ca06 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_mips64 #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_mips64 #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_mips64 +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_mips64 +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_mips64 +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_mips64 +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 80633733..283f5796 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_mips64el #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_mips64el #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_mips64el +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_mips64el +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_mips64el +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_mips64el +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 338e0c3e..1b324aac 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_mipsel #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_mipsel #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_mipsel +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_mipsel +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_mipsel +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_mipsel +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 6d53ec17..cf916403 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_powerpc #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_powerpc #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_powerpc +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_powerpc +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_powerpc +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_powerpc +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 a0857839..f55c1747 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_riscv32 #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_riscv32 #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_riscv32 +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_riscv32 +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_riscv32 +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_riscv32 +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 a071be08..f210ccd6 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_riscv64 #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_riscv64 #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_riscv64 +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_riscv64 +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_riscv64 +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_riscv64 +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 6dff0138..5ea77b8a 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_sparc #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_sparc #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_sparc +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_sparc +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_sparc +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_sparc +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 77fce46c..08e57d74 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_sparc64 #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_sparc64 #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_sparc64 +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_sparc64 +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_sparc64 +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_sparc64 +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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 6787f362..179b6b35 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -631,6 +631,11 @@ DEF_HELPER_FLAGS_4(gvec_vcvt_uh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_hs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(gvec_vcvt_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_rm_ss, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_rm_us, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_rm_sh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(gvec_vcvt_rm_uh, 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 8a47a3b3..77bf8d99 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -3879,76 +3879,46 @@ DO_VRINT(VRINTZ, FPROUNDING_ZERO) DO_VRINT(VRINTM, FPROUNDING_NEGINF) DO_VRINT(VRINTP, FPROUNDING_POSINF) -static bool do_vcvt(DisasContext *s, arg_2misc *a, int rmode, bool is_signed) -{ - /* - * Handle a VCVT* operation by iterating 32 bits at a time, - * with a specified rounding mode in operation. - */ - int pass; - TCGv_ptr fpst; - TCGv_i32 tcg_rmode, tcg_shift; - TCGContext *tcg_ctx = s->uc->tcg_ctx; - - if (!arm_dc_feature(s, ARM_FEATURE_NEON) || - !arm_dc_feature(s, ARM_FEATURE_V8)) { - return false; +#define DO_VEC_RMODE(INSN, RMODE, OP) \ + static void gen_##INSN(TCGContext *s, unsigned vece, uint32_t rd_ofs, \ + uint32_t rm_ofs, \ + uint32_t oprsz, uint32_t maxsz) \ + { \ + static gen_helper_gvec_2_ptr * const fns[4] = { \ + NULL, \ + gen_helper_gvec_##OP##h, \ + gen_helper_gvec_##OP##s, \ + NULL, \ + }; \ + TCGv_ptr fpst; \ + fpst = fpstatus_ptr(s, vece == 1 ? FPST_STD_F16 : FPST_STD); \ + tcg_gen_gvec_2_ptr(s, rd_ofs, rm_ofs, fpst, oprsz, maxsz, \ + arm_rmode_to_sf(RMODE), fns[vece]); \ + tcg_temp_free_ptr(s, fpst); \ + } \ + static bool trans_##INSN(DisasContext *s, arg_2misc *a) \ + { \ + if (!arm_dc_feature(s, ARM_FEATURE_V8)) { \ + return false; \ + } \ + if (a->size == MO_16) { \ + if (!dc_isar_feature(aa32_fp16_arith, s)) { \ + return false; \ + } \ + } else if (a->size != MO_32) { \ + return false; \ + } \ + return do_2misc_vec(s, a, gen_##INSN); \ } - /* 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); - tcg_shift = tcg_const_i32(tcg_ctx, 0); - tcg_rmode = tcg_const_i32(tcg_ctx, arm_rmode_to_sf(rmode)); - gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env); - for (pass = 0; pass < (a->q ? 4 : 2); pass++) { - TCGv_i32 tmp = neon_load_reg(s, a->vm, pass); - if (is_signed) { - gen_helper_vfp_tosls(tcg_ctx, tmp, tmp, tcg_shift, fpst); - } else { - gen_helper_vfp_touls(tcg_ctx, tmp, tmp, tcg_shift, fpst); - } - neon_store_reg(s, a->vd, pass, tmp); - } - gen_helper_set_neon_rmode(tcg_ctx, tcg_rmode, tcg_rmode, tcg_ctx->cpu_env); - tcg_temp_free_i32(tcg_ctx, tcg_rmode); - tcg_temp_free_i32(tcg_ctx, tcg_shift); - tcg_temp_free_ptr(tcg_ctx, fpst); - - return true; -} - -#define DO_VCVT(INSN, RMODE, SIGNED) \ - static bool trans_##INSN(DisasContext *s, arg_2misc *a) \ - { \ - return do_vcvt(s, a, RMODE, SIGNED); \ - } - -DO_VCVT(VCVTAU, FPROUNDING_TIEAWAY, false) -DO_VCVT(VCVTAS, FPROUNDING_TIEAWAY, true) -DO_VCVT(VCVTNU, FPROUNDING_TIEEVEN, false) -DO_VCVT(VCVTNS, FPROUNDING_TIEEVEN, true) -DO_VCVT(VCVTPU, FPROUNDING_POSINF, false) -DO_VCVT(VCVTPS, FPROUNDING_POSINF, true) -DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false) -DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true) +DO_VEC_RMODE(VCVTAU, FPROUNDING_TIEAWAY, vcvt_rm_u) +DO_VEC_RMODE(VCVTAS, FPROUNDING_TIEAWAY, vcvt_rm_s) +DO_VEC_RMODE(VCVTNU, FPROUNDING_TIEEVEN, vcvt_rm_u) +DO_VEC_RMODE(VCVTNS, FPROUNDING_TIEEVEN, vcvt_rm_s) +DO_VEC_RMODE(VCVTPU, FPROUNDING_POSINF, vcvt_rm_u) +DO_VEC_RMODE(VCVTPS, FPROUNDING_POSINF, vcvt_rm_s) +DO_VEC_RMODE(VCVTMU, FPROUNDING_NEGINF, vcvt_rm_u) +DO_VEC_RMODE(VCVTMS, FPROUNDING_NEGINF, vcvt_rm_s) static bool trans_VSWP(DisasContext *s, arg_2misc *a) { diff --git a/qemu/target/arm/vec_helper.c b/qemu/target/arm/vec_helper.c index 772853a9..489eabd5 100644 --- a/qemu/target/arm/vec_helper.c +++ b/qemu/target/arm/vec_helper.c @@ -1869,3 +1869,26 @@ DO_VCVT_FIXED(gvec_vcvt_hs, helper_vfp_toshh_round_to_zero, uint16_t) DO_VCVT_FIXED(gvec_vcvt_hu, helper_vfp_touhh_round_to_zero, uint16_t) #undef DO_VCVT_FIXED + +#define DO_VCVT_RMODE(NAME, FUNC, TYPE) \ + void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \ + { \ + float_status *fpst = stat; \ + intptr_t i, oprsz = simd_oprsz(desc); \ + uint32_t rmode = simd_data(desc); \ + uint32_t prev_rmode = get_float_rounding_mode(fpst); \ + TYPE *d = vd, *n = vn; \ + set_float_rounding_mode(rmode, fpst); \ + for (i = 0; i < oprsz / sizeof(TYPE); i++) { \ + d[i] = FUNC(n[i], 0, fpst); \ + } \ + set_float_rounding_mode(prev_rmode, fpst); \ + clear_tail(d, oprsz, simd_maxsz(desc)); \ + } + +DO_VCVT_RMODE(gvec_vcvt_rm_ss, helper_vfp_tosls, uint32_t) +DO_VCVT_RMODE(gvec_vcvt_rm_us, helper_vfp_touls, uint32_t) +DO_VCVT_RMODE(gvec_vcvt_rm_sh, helper_vfp_toshh, uint16_t) +DO_VCVT_RMODE(gvec_vcvt_rm_uh, helper_vfp_touhh, uint16_t) + +#undef DO_VCVT_RMODE diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 0c77cf9b..a0db8d6e 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1844,6 +1844,10 @@ #define helper_gvec_vcvt_uh helper_gvec_vcvt_uh_x86_64 #define helper_gvec_vcvt_hs helper_gvec_vcvt_hs_x86_64 #define helper_gvec_vcvt_hu helper_gvec_vcvt_hu_x86_64 +#define helper_gvec_vcvt_rm_ss helper_gvec_vcvt_rm_ss_x86_64 +#define helper_gvec_vcvt_rm_us helper_gvec_vcvt_rm_us_x86_64 +#define helper_gvec_vcvt_rm_sh helper_gvec_vcvt_rm_sh_x86_64 +#define helper_gvec_vcvt_rm_uh helper_gvec_vcvt_rm_uh_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