The VFP cmp operations do a comparison and then store the result in FPSCR. For AArch64, we need to compare but store the result in normal PSTATE instead. So split the comparison from FPSCR modifications.
Signed-off-by: Alexander Graf <ag...@suse.de> --- target-arm/helper.c | 14 ++++++++++++-- target-arm/helper.h | 12 ++++++++---- target-arm/translate.c | 8 ++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 24e8ae4..2b031a8 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3604,7 +3604,7 @@ float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env) /* XXX: check quiet/signaling case */ #define DO_VFP_cmp(p, type) \ -void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ +uint32_t VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ { \ uint32_t flags; \ switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \ @@ -3614,10 +3614,15 @@ void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \ default: \ case float_relation_unordered: flags = PSTATE_V | PSTATE_C; break; \ } \ + return flags; \ +} \ +void VFP_HELPER(fpscr_cmp, p)(type a, type b, CPUARMState *env) \ +{ \ + uint32_t flags = VFP_HELPER(cmp, p)(a, b, env); \ env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ } \ -void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ +uint32_t VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ { \ uint32_t flags; \ switch(type ## _compare(a, b, &env->vfp.fp_status)) { \ @@ -3627,6 +3632,11 @@ void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \ default: \ case float_relation_unordered: flags = PSTATE_V | PSTATE_C; break; \ } \ + return flags; \ +} \ +void VFP_HELPER(fpscr_cmpe, p)(type a, type b, CPUARMState *env) \ +{ \ + uint32_t flags = VFP_HELPER(cmpe, p)(a, b, env); \ env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ } diff --git a/target-arm/helper.h b/target-arm/helper.h index 63ae13a..e66362a 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -85,10 +85,14 @@ DEF_HELPER_1(vfp_abss, f32, f32) DEF_HELPER_1(vfp_absd, f64, f64) DEF_HELPER_2(vfp_sqrts, f32, f32, env) DEF_HELPER_2(vfp_sqrtd, f64, f64, env) -DEF_HELPER_3(vfp_cmps, void, f32, f32, env) -DEF_HELPER_3(vfp_cmpd, void, f64, f64, env) -DEF_HELPER_3(vfp_cmpes, void, f32, f32, env) -DEF_HELPER_3(vfp_cmped, void, f64, f64, env) +DEF_HELPER_3(vfp_fpscr_cmps, void, f32, f32, env) +DEF_HELPER_3(vfp_fpscr_cmpd, void, f64, f64, env) +DEF_HELPER_3(vfp_fpscr_cmpes, void, f32, f32, env) +DEF_HELPER_3(vfp_fpscr_cmped, void, f64, f64, env) +DEF_HELPER_3(vfp_cmps, i32, f32, f32, env) +DEF_HELPER_3(vfp_cmpd, i32, f64, f64, env) +DEF_HELPER_3(vfp_cmpes, i32, f32, f32, env) +DEF_HELPER_3(vfp_cmped, i32, f64, f64, env) DEF_HELPER_2(vfp_fcvtds, f64, f32, env) DEF_HELPER_2(vfp_fcvtsd, f32, f64, env) diff --git a/target-arm/translate.c b/target-arm/translate.c index b0a25ca..ef284da 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -1059,17 +1059,17 @@ static inline void gen_vfp_sqrt(int dp) static inline void gen_vfp_cmp(int dp) { if (dp) - gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env); + gen_helper_vfp_fpscr_cmpd(cpu_F0d, cpu_F1d, cpu_env); else - gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env); + gen_helper_vfp_fpscr_cmps(cpu_F0s, cpu_F1s, cpu_env); } static inline void gen_vfp_cmpe(int dp) { if (dp) - gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env); + gen_helper_vfp_fpscr_cmped(cpu_F0d, cpu_F1d, cpu_env); else - gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env); + gen_helper_vfp_fpscr_cmpes(cpu_F0s, cpu_F1s, cpu_env); } static inline void gen_vfp_F1_ld0(int dp) -- 1.7.12.4