target/arm: Implement VFP fp16 VCMP
Implement fp16 version of VCMP. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200828183354.27913-11-peter.maydell@linaro.org
This commit is contained in:
parent
28c28728e5
commit
1b88b054c5
@ -134,8 +134,10 @@ DEF_HELPER_1(vfp_absd, f64, f64)
|
|||||||
DEF_HELPER_2(vfp_sqrth, f16, f16, env)
|
DEF_HELPER_2(vfp_sqrth, f16, f16, env)
|
||||||
DEF_HELPER_2(vfp_sqrts, f32, f32, env)
|
DEF_HELPER_2(vfp_sqrts, f32, f32, env)
|
||||||
DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
|
DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
|
||||||
|
DEF_HELPER_3(vfp_cmph, void, f16, f16, env)
|
||||||
DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
|
DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
|
||||||
DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
|
DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
|
||||||
|
DEF_HELPER_3(vfp_cmpeh, void, f16, f16, env)
|
||||||
DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
|
DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
|
||||||
DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
|
DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
|
||||||
|
|
||||||
|
@ -2325,6 +2325,45 @@ DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp)
|
|||||||
DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp)
|
DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp)
|
||||||
DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp)
|
DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp)
|
||||||
|
|
||||||
|
static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
|
||||||
|
{
|
||||||
|
TCGv_i32 vd, vm;
|
||||||
|
|
||||||
|
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();
|
||||||
|
vm = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
neon_load_reg32(vd, a->vd);
|
||||||
|
if (a->z) {
|
||||||
|
tcg_gen_movi_i32(vm, 0);
|
||||||
|
} else {
|
||||||
|
neon_load_reg32(vm, a->vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->e) {
|
||||||
|
gen_helper_vfp_cmpeh(vd, vm, cpu_env);
|
||||||
|
} else {
|
||||||
|
gen_helper_vfp_cmph(vd, vm, cpu_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
tcg_temp_free_i32(vd);
|
||||||
|
tcg_temp_free_i32(vm);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
|
static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
|
||||||
{
|
{
|
||||||
TCGv_i32 vd, vm;
|
TCGv_i32 vd, vm;
|
||||||
|
@ -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_sp ---- 1110 1.11 0001 .... 1010 11.0 .... @vfp_dm_ss
|
||||||
VSQRT_dp ---- 1110 1.11 0001 .... 1011 11.0 .... @vfp_dm_dd
|
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 .... \
|
VCMP_sp ---- 1110 1.11 010 z:1 .... 1010 e:1 1.0 .... \
|
||||||
vd=%vd_sp vm=%vm_sp
|
vd=%vd_sp vm=%vm_sp
|
||||||
VCMP_dp ---- 1110 1.11 010 z:1 .... 1011 e:1 1.0 .... \
|
VCMP_dp ---- 1110 1.11 010 z:1 .... 1011 e:1 1.0 .... \
|
||||||
|
@ -330,19 +330,20 @@ static void softfloat_to_vfp_compare(CPUARMState *env, FloatRelation cmp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: check quiet/signaling case */
|
/* XXX: check quiet/signaling case */
|
||||||
#define DO_VFP_cmp(p, type) \
|
#define DO_VFP_cmp(P, FLOATTYPE, ARGTYPE, FPST) \
|
||||||
void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
|
void VFP_HELPER(cmp, P)(ARGTYPE a, ARGTYPE b, CPUARMState *env) \
|
||||||
{ \
|
{ \
|
||||||
softfloat_to_vfp_compare(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, \
|
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(h, float16, dh_ctype_f16, fp_status_f16)
|
||||||
DO_VFP_cmp(d, float64)
|
DO_VFP_cmp(s, float32, float32, fp_status)
|
||||||
|
DO_VFP_cmp(d, float64, float64, fp_status)
|
||||||
#undef DO_VFP_cmp
|
#undef DO_VFP_cmp
|
||||||
|
|
||||||
/* Integer to float and float to integer conversions */
|
/* Integer to float and float to integer conversions */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user