From e9d652824b05845f143ef4797d707fae47d4b3ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 1 Jul 2019 17:26:21 +0100 Subject: target/arm/vfp_helper: Extract vfp_set_fpscr_to_host() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vfp_set_fpscr() helper contains code specific to the host floating point implementation (here the SoftFloat library). Extract this code to vfp_set_fpscr_to_host(). Signed-off-by: Philippe Mathieu-Daudé Message-id: 20190701132516.26392-16-philmd@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/vfp_helper.c | 101 +++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 48 deletions(-) (limited to 'target/arm/vfp_helper.c') diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index d54e325324..b19a395b67 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -81,6 +81,58 @@ static inline int vfp_exceptbits_to_host(int target_bits) return host_bits; } +static void vfp_set_fpscr_to_host(CPUARMState *env, uint32_t val) +{ + int i; + uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR]; + + changed ^= val; + if (changed & (3 << 22)) { + i = (val >> 22) & 3; + switch (i) { + case FPROUNDING_TIEEVEN: + i = float_round_nearest_even; + break; + case FPROUNDING_POSINF: + i = float_round_up; + break; + case FPROUNDING_NEGINF: + i = float_round_down; + break; + case FPROUNDING_ZERO: + i = float_round_to_zero; + break; + } + set_float_rounding_mode(i, &env->vfp.fp_status); + set_float_rounding_mode(i, &env->vfp.fp_status_f16); + } + if (changed & FPCR_FZ16) { + bool ftz_enabled = val & FPCR_FZ16; + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); + } + if (changed & FPCR_FZ) { + bool ftz_enabled = val & FPCR_FZ; + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status); + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status); + } + if (changed & FPCR_DN) { + bool dnan_enabled = val & FPCR_DN; + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status); + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); + } + + /* + * The exception flags are ORed together when we read fpscr so we + * only need to preserve the current state in one of our + * float_status values. + */ + i = vfp_exceptbits_to_host(val); + set_float_exception_flags(i, &env->vfp.fp_status); + set_float_exception_flags(0, &env->vfp.fp_status_f16); + set_float_exception_flags(0, &env->vfp.standard_fp_status); +} + uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env) { uint32_t i, fpscr; @@ -109,9 +161,6 @@ uint32_t vfp_get_fpscr(CPUARMState *env) void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) { - int i; - uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR]; - /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */ if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) { val &= ~FPCR_FZ16; @@ -146,51 +195,7 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val) env->vfp.qc[2] = 0; env->vfp.qc[3] = 0; - changed ^= val; - if (changed & (3 << 22)) { - i = (val >> 22) & 3; - switch (i) { - case FPROUNDING_TIEEVEN: - i = float_round_nearest_even; - break; - case FPROUNDING_POSINF: - i = float_round_up; - break; - case FPROUNDING_NEGINF: - i = float_round_down; - break; - case FPROUNDING_ZERO: - i = float_round_to_zero; - break; - } - set_float_rounding_mode(i, &env->vfp.fp_status); - set_float_rounding_mode(i, &env->vfp.fp_status_f16); - } - if (changed & FPCR_FZ16) { - bool ftz_enabled = val & FPCR_FZ16; - set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); - } - if (changed & FPCR_FZ) { - bool ftz_enabled = val & FPCR_FZ; - set_flush_to_zero(ftz_enabled, &env->vfp.fp_status); - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status); - } - if (changed & FPCR_DN) { - bool dnan_enabled = val & FPCR_DN; - set_default_nan_mode(dnan_enabled, &env->vfp.fp_status); - set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); - } - - /* - * The exception flags are ORed together when we read fpscr so we - * only need to preserve the current state in one of our - * float_status values. - */ - i = vfp_exceptbits_to_host(val); - set_float_exception_flags(i, &env->vfp.fp_status); - set_float_exception_flags(0, &env->vfp.fp_status_f16); - set_float_exception_flags(0, &env->vfp.standard_fp_status); + vfp_set_fpscr_to_host(env, val); } void vfp_set_fpscr(CPUARMState *env, uint32_t val) -- cgit v1.2.3