diff --git a/target/alpha/helper.c b/target/alpha/helper.c index 10602fb339..e21c488aa3 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c @@ -46,19 +46,8 @@ void cpu_alpha_store_fpcr(CPUAlphaState *env, uint64_t val) uint32_t fpcr = val >> 32; uint32_t t = 0; - t |= CONVERT_BIT(fpcr, FPCR_INED, FPCR_INE); - t |= CONVERT_BIT(fpcr, FPCR_UNFD, FPCR_UNF); - t |= CONVERT_BIT(fpcr, FPCR_OVFD, FPCR_OVF); - t |= CONVERT_BIT(fpcr, FPCR_DZED, FPCR_DZE); - t |= CONVERT_BIT(fpcr, FPCR_INVD, FPCR_INV); - + /* Record the raw value before adjusting for linux-user. */ env->fpcr = fpcr; - env->fpcr_exc_enable = ~t & FPCR_STATUS_MASK; - - env->fpcr_dyn_round = rm_map[(fpcr & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT]; - - env->fpcr_flush_to_zero = (fpcr & FPCR_UNFD) && (fpcr & FPCR_UNDZ); - env->fp_status.flush_inputs_to_zero = (fpcr & FPCR_DNZ) != 0; #ifdef CONFIG_USER_ONLY /* @@ -67,13 +56,29 @@ void cpu_alpha_store_fpcr(CPUAlphaState *env, uint64_t val) * which point the kernel's handler would emulate and apply * the software exception mask. */ + uint32_t soft_fpcr = alpha_ieee_swcr_to_fpcr(env->swcr) >> 32; + fpcr |= soft_fpcr & FPCR_STATUS_MASK; +#endif + + t |= CONVERT_BIT(fpcr, FPCR_INED, FPCR_INE); + t |= CONVERT_BIT(fpcr, FPCR_UNFD, FPCR_UNF); + t |= CONVERT_BIT(fpcr, FPCR_OVFD, FPCR_OVF); + t |= CONVERT_BIT(fpcr, FPCR_DZED, FPCR_DZE); + t |= CONVERT_BIT(fpcr, FPCR_INVD, FPCR_INV); + + env->fpcr_exc_enable = ~t & FPCR_STATUS_MASK; + + env->fpcr_dyn_round = rm_map[(fpcr & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT]; + + env->fpcr_flush_to_zero = (fpcr & FPCR_UNFD) && (fpcr & FPCR_UNDZ); + env->fp_status.flush_inputs_to_zero = (fpcr & FPCR_DNZ) != 0; +#ifdef CONFIG_USER_ONLY if (env->swcr & SWCR_MAP_DMZ) { env->fp_status.flush_inputs_to_zero = 1; } if (env->swcr & SWCR_MAP_UMZ) { env->fpcr_flush_to_zero = 1; } - env->fpcr_exc_enable &= ~(alpha_ieee_swcr_to_fpcr(env->swcr) >> 32); #endif }