From 5d98e14545984e32239d53bbb1427645e4029a95 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sun, 28 Feb 2021 04:55:06 -0500 Subject: [PATCH] target/arm: Implement VFP fp16 VCMP Implement fp16 version of VCMP. Backports 1b88b054c5b201e8581114d29527c6a5a7e088c9 --- 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 | 2 ++ qemu/target/arm/translate-vfp.inc.c | 40 +++++++++++++++++++++++++++++ qemu/target/arm/vfp.decode | 2 ++ qemu/target/arm/vfp_helper.c | 15 ++++++----- qemu/x86_64.h | 2 ++ 20 files changed, 84 insertions(+), 7 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 6763c071..f23c5921 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_aarch64 #define helper_vfp_adds helper_vfp_adds_aarch64 #define helper_vfp_cmpd helper_vfp_cmpd_aarch64 +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_aarch64 #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_aarch64 #define helper_vfp_cmped helper_vfp_cmped_aarch64 +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_aarch64 #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_aarch64 #define helper_vfp_cmpes helper_vfp_cmpes_aarch64 #define helper_vfp_cmps helper_vfp_cmps_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index ba399547..361abce5 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_aarch64eb #define helper_vfp_adds helper_vfp_adds_aarch64eb #define helper_vfp_cmpd helper_vfp_cmpd_aarch64eb +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_aarch64eb #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_aarch64eb #define helper_vfp_cmped helper_vfp_cmped_aarch64eb +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_aarch64eb #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_aarch64eb #define helper_vfp_cmpes helper_vfp_cmpes_aarch64eb #define helper_vfp_cmps helper_vfp_cmps_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 4f9f01d6..8f2a936d 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_arm #define helper_vfp_adds helper_vfp_adds_arm #define helper_vfp_cmpd helper_vfp_cmpd_arm +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_arm #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_arm #define helper_vfp_cmped helper_vfp_cmped_arm +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_arm #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_arm #define helper_vfp_cmpes helper_vfp_cmpes_arm #define helper_vfp_cmps helper_vfp_cmps_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 27ce8604..52818349 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_armeb #define helper_vfp_adds helper_vfp_adds_armeb #define helper_vfp_cmpd helper_vfp_cmpd_armeb +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_armeb #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_armeb #define helper_vfp_cmped helper_vfp_cmped_armeb +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_armeb #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_armeb #define helper_vfp_cmpes helper_vfp_cmpes_armeb #define helper_vfp_cmps helper_vfp_cmps_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index a98903c7..6fef404a 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1898,8 +1898,10 @@ symbols = ( 'helper_vfp_addh', 'helper_vfp_adds', 'helper_vfp_cmpd', + 'helper_vfp_cmph_a32', 'helper_vfp_cmph_a64', 'helper_vfp_cmped', + 'helper_vfp_cmpeh_a32', 'helper_vfp_cmpeh_a64', 'helper_vfp_cmpes', 'helper_vfp_cmps', diff --git a/qemu/m68k.h b/qemu/m68k.h index e07c4985..668bee7e 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_m68k #define helper_vfp_adds helper_vfp_adds_m68k #define helper_vfp_cmpd helper_vfp_cmpd_m68k +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_m68k #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_m68k #define helper_vfp_cmped helper_vfp_cmped_m68k +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_m68k #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_m68k #define helper_vfp_cmpes helper_vfp_cmpes_m68k #define helper_vfp_cmps helper_vfp_cmps_m68k diff --git a/qemu/mips.h b/qemu/mips.h index f77f46ae..7fc586a9 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_mips #define helper_vfp_adds helper_vfp_adds_mips #define helper_vfp_cmpd helper_vfp_cmpd_mips +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_mips #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_mips #define helper_vfp_cmped helper_vfp_cmped_mips +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_mips #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_mips #define helper_vfp_cmpes helper_vfp_cmpes_mips #define helper_vfp_cmps helper_vfp_cmps_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 124c2aee..bcbbdc4a 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_mips64 #define helper_vfp_adds helper_vfp_adds_mips64 #define helper_vfp_cmpd helper_vfp_cmpd_mips64 +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_mips64 #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_mips64 #define helper_vfp_cmped helper_vfp_cmped_mips64 +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_mips64 #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_mips64 #define helper_vfp_cmpes helper_vfp_cmpes_mips64 #define helper_vfp_cmps helper_vfp_cmps_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index c86d8898..98f5d38f 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_mips64el #define helper_vfp_adds helper_vfp_adds_mips64el #define helper_vfp_cmpd helper_vfp_cmpd_mips64el +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_mips64el #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_mips64el #define helper_vfp_cmped helper_vfp_cmped_mips64el +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_mips64el #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_mips64el #define helper_vfp_cmpes helper_vfp_cmpes_mips64el #define helper_vfp_cmps helper_vfp_cmps_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 0c51e1c3..3387fac2 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_mipsel #define helper_vfp_adds helper_vfp_adds_mipsel #define helper_vfp_cmpd helper_vfp_cmpd_mipsel +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_mipsel #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_mipsel #define helper_vfp_cmped helper_vfp_cmped_mipsel +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_mipsel #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_mipsel #define helper_vfp_cmpes helper_vfp_cmpes_mipsel #define helper_vfp_cmps helper_vfp_cmps_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 6362032d..26e26568 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_powerpc #define helper_vfp_adds helper_vfp_adds_powerpc #define helper_vfp_cmpd helper_vfp_cmpd_powerpc +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_powerpc #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_powerpc #define helper_vfp_cmped helper_vfp_cmped_powerpc +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_powerpc #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_powerpc #define helper_vfp_cmpes helper_vfp_cmpes_powerpc #define helper_vfp_cmps helper_vfp_cmps_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 043430bc..e997b6f4 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_riscv32 #define helper_vfp_adds helper_vfp_adds_riscv32 #define helper_vfp_cmpd helper_vfp_cmpd_riscv32 +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_riscv32 #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_riscv32 #define helper_vfp_cmped helper_vfp_cmped_riscv32 +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_riscv32 #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_riscv32 #define helper_vfp_cmpes helper_vfp_cmpes_riscv32 #define helper_vfp_cmps helper_vfp_cmps_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 8acf06ab..e8d83205 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_riscv64 #define helper_vfp_adds helper_vfp_adds_riscv64 #define helper_vfp_cmpd helper_vfp_cmpd_riscv64 +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_riscv64 #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_riscv64 #define helper_vfp_cmped helper_vfp_cmped_riscv64 +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_riscv64 #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_riscv64 #define helper_vfp_cmpes helper_vfp_cmpes_riscv64 #define helper_vfp_cmps helper_vfp_cmps_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index f56607cb..f8d0470b 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_sparc #define helper_vfp_adds helper_vfp_adds_sparc #define helper_vfp_cmpd helper_vfp_cmpd_sparc +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_sparc #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_sparc #define helper_vfp_cmped helper_vfp_cmped_sparc +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_sparc #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_sparc #define helper_vfp_cmpes helper_vfp_cmpes_sparc #define helper_vfp_cmps helper_vfp_cmps_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index cca8d433..4cebf11c 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_sparc64 #define helper_vfp_adds helper_vfp_adds_sparc64 #define helper_vfp_cmpd helper_vfp_cmpd_sparc64 +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_sparc64 #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_sparc64 #define helper_vfp_cmped helper_vfp_cmped_sparc64 +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_sparc64 #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_sparc64 #define helper_vfp_cmpes helper_vfp_cmpes_sparc64 #define helper_vfp_cmps helper_vfp_cmps_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index ded20856..86da6c39 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -132,8 +132,10 @@ DEF_HELPER_1(vfp_absd, f64, f64) DEF_HELPER_2(vfp_sqrth, f16, f16, env) DEF_HELPER_2(vfp_sqrts, f32, f32, env) DEF_HELPER_2(vfp_sqrtd, f64, f64, env) +DEF_HELPER_3(vfp_cmph_a32, void, f16, f16, env) DEF_HELPER_3(vfp_cmps, void, f32, f32, env) DEF_HELPER_3(vfp_cmpd, void, f64, f64, env) +DEF_HELPER_3(vfp_cmpeh_a32, void, f16, f16, env) DEF_HELPER_3(vfp_cmpes, void, f32, f32, env) DEF_HELPER_3(vfp_cmped, void, f64, f64, env) diff --git a/qemu/target/arm/translate-vfp.inc.c b/qemu/target/arm/translate-vfp.inc.c index ec4d6469..2ac733b1 100644 --- a/qemu/target/arm/translate-vfp.inc.c +++ b/qemu/target/arm/translate-vfp.inc.c @@ -2355,6 +2355,46 @@ DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp) DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp) DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp) +static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a) +{ + TCGv_i32 vd, vm; + TCGContext *tcg_ctx = s->uc->tcg_ctx; + + if (!dc_isar_feature(aa32_fp16_arith, s)) { + return false; + } + + /* Vm/M bits must be zero for the Z variant */ + if (a->z && a->vm != 0) { + return false; + } + + if (!vfp_access_check(s)) { + return true; + } + + vd = tcg_temp_new_i32(tcg_ctx); + vm = tcg_temp_new_i32(tcg_ctx); + + neon_load_reg32(s, vd, a->vd); + if (a->z) { + tcg_gen_movi_i32(tcg_ctx, vm, 0); + } else { + neon_load_reg32(s, vm, a->vm); + } + + if (a->e) { + gen_helper_vfp_cmpeh_a32(tcg_ctx, vd, vm, tcg_ctx->cpu_env); + } else { + gen_helper_vfp_cmph_a32(tcg_ctx, vd, vm, tcg_ctx->cpu_env); + } + + tcg_temp_free_i32(tcg_ctx, vd); + tcg_temp_free_i32(tcg_ctx, vm); + + return true; +} + static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a) { TCGContext *tcg_ctx = s->uc->tcg_ctx; diff --git a/qemu/target/arm/vfp.decode b/qemu/target/arm/vfp.decode index c8981837..b213da4b 100644 --- a/qemu/target/arm/vfp.decode +++ b/qemu/target/arm/vfp.decode @@ -176,6 +176,8 @@ VSQRT_hp ---- 1110 1.11 0001 .... 1001 11.0 .... @vfp_dm_ss VSQRT_sp ---- 1110 1.11 0001 .... 1010 11.0 .... @vfp_dm_ss VSQRT_dp ---- 1110 1.11 0001 .... 1011 11.0 .... @vfp_dm_dd +VCMP_hp ---- 1110 1.11 010 z:1 .... 1001 e:1 1.0 .... \ + vd=%vd_sp vm=%vm_sp VCMP_sp ---- 1110 1.11 010 z:1 .... 1010 e:1 1.0 .... \ vd=%vd_sp vm=%vm_sp VCMP_dp ---- 1110 1.11 010 z:1 .... 1011 e:1 1.0 .... \ diff --git a/qemu/target/arm/vfp_helper.c b/qemu/target/arm/vfp_helper.c index fbe8185c..49c6b550 100644 --- a/qemu/target/arm/vfp_helper.c +++ b/qemu/target/arm/vfp_helper.c @@ -333,19 +333,20 @@ static void softfloat_to_vfp_compare(CPUARMState *env, FloatRelation cmp) } /* XXX: check quiet/signaling case */ -#define DO_VFP_cmp(p, type) \ -void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ +#define DO_VFP_cmp(P, FLOATTYPE, ARGTYPE, FPST) \ +void VFP_HELPER(cmp, P)(ARGTYPE a, ARGTYPE b, CPUARMState *env) \ { \ softfloat_to_vfp_compare(env, \ - type ## _compare_quiet(a, b, &env->vfp.fp_status)); \ + FLOATTYPE ## _compare_quiet(a, b, &env->vfp.FPST)); \ } \ -void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ +void VFP_HELPER(cmpe, P)(ARGTYPE a, ARGTYPE b, CPUARMState *env) \ { \ softfloat_to_vfp_compare(env, \ - type ## _compare(a, b, &env->vfp.fp_status)); \ + FLOATTYPE ## _compare(a, b, &env->vfp.FPST)); \ } -DO_VFP_cmp(s, float32) -DO_VFP_cmp(d, float64) +DO_VFP_cmp(h_a32, float16, dh_ctype_f16, fp_status_f16) +DO_VFP_cmp(s, float32, float32, fp_status) +DO_VFP_cmp(d, float64, float64, fp_status) #undef DO_VFP_cmp /* Integer to float and float to integer conversions */ diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 15fbf1e6..c5bf81ea 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1892,8 +1892,10 @@ #define helper_vfp_addh helper_vfp_addh_x86_64 #define helper_vfp_adds helper_vfp_adds_x86_64 #define helper_vfp_cmpd helper_vfp_cmpd_x86_64 +#define helper_vfp_cmph_a32 helper_vfp_cmph_a32_x86_64 #define helper_vfp_cmph_a64 helper_vfp_cmph_a64_x86_64 #define helper_vfp_cmped helper_vfp_cmped_x86_64 +#define helper_vfp_cmpeh_a32 helper_vfp_cmpeh_a32_x86_64 #define helper_vfp_cmpeh_a64 helper_vfp_cmpeh_a64_x86_64 #define helper_vfp_cmpes helper_vfp_cmpes_x86_64 #define helper_vfp_cmps helper_vfp_cmps_x86_64