path: root/target/arm/vfp_helper.c
diff options
authorPeter Maydell <peter.maydell@linaro.org>2020-08-06 11:44:52 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-08-24 10:15:11 +0100
commitaaae563bc73de0598bbc09a102e68f27fafe704a (patch)
treec2362da0fd9d29b9f9469947f60edae8ac4364a6 /target/arm/vfp_helper.c
parenta84d1d1316726704edd2617b2c30c921d98a8137 (diff)
target/arm: Implement FPST_STD_F16 fpstatus
Architecturally, Neon FP16 operations use the "standard FPSCR" like all other Neon operations. However, this is defined in the Arm ARM pseudocode as "a fixed value, except that FZ16 (and AHP) follow the FPSCR bits". In QEMU, the softfloat float_status doesn't include separate flush-to-zero for FP16 operations, so we must keep separate fp_status for "Neon non-FP16" and "Neon fp16" operations, in the same way we do already for the non-Neon "fp_status" vs "fp_status_f16". Add the extra float_status field to the CPU state structure, ensure it is correctly initialized and updated on FPSCR writes, and make fpstatus_ptr(FPST_STD_F16) return a pointer to it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20200806104453.30393-4-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/vfp_helper.c')
1 files changed, 5 insertions, 0 deletions
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index 60dcd4bf14..64266ece62 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -93,6 +93,8 @@ static uint32_t vfp_get_fpscr_from_host(CPUARMState *env)
/* FZ16 does not generate an input denormal exception. */
i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
& ~float_flag_input_denormal);
+ i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16)
+ & ~float_flag_input_denormal);
return vfp_exceptbits_from_host(i);
@@ -124,7 +126,9 @@ static void vfp_set_fpscr_to_host(CPUARMState *env, uint32_t val)
if (changed & FPCR_FZ16) {
bool ftz_enabled = val & FPCR_FZ16;
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
+ set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16);
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16);
if (changed & FPCR_FZ) {
bool ftz_enabled = val & FPCR_FZ;
@@ -146,6 +150,7 @@ static void vfp_set_fpscr_to_host(CPUARMState *env, uint32_t 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);
+ set_float_exception_flags(0, &env->vfp.standard_fp_status_f16);