diff mbox series

[v3,03/33] target/alpha: Fix SWCR_TRAP_ENABLE_MASK

Message ID 20190924210106.27117-4-alex.bennee@linaro.org (mailing list archive)
State New, archived
Headers show
Series testing/next (docker,tcg, alpha ;-) | expand

Commit Message

Alex Bennée Sept. 24, 2019, 9 p.m. UTC
From: Richard Henderson <richard.henderson@linaro.org>

The CONFIG_USER_ONLY adjustment blindly mashed the swcr
exception enable bits into the fpcr exception disable bits.

However, fpcr_exc_enable has already converted the exception
disable bits into the exception status bits in order to make
it easier to mask status bits at runtime.

Instead, merge the swcr enable bits with the fpcr before we
convert to status bits.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20190921043256.4575-4-richard.henderson@linaro.org>
---
 target/alpha/helper.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

Comments

Philippe Mathieu-Daudé Sept. 25, 2019, 10:35 p.m. UTC | #1
On 9/24/19 11:00 PM, Alex Bennée wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> The CONFIG_USER_ONLY adjustment blindly mashed the swcr
> exception enable bits into the fpcr exception disable bits.
> 
> However, fpcr_exc_enable has already converted the exception
> disable bits into the exception status bits in order to make
> it easier to mask status bits at runtime.
> 
> Instead, merge the swcr enable bits with the fpcr before we
> convert to status bits.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Message-Id: <20190921043256.4575-4-richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>  target/alpha/helper.c | 23 ++++++++++++++---------
>  1 file changed, 14 insertions(+), 9 deletions(-)
> 
> diff --git a/target/alpha/helper.c b/target/alpha/helper.c
> index 10602fb3394..e21c488aa32 100644
> --- a/target/alpha/helper.c
> +++ b/target/alpha/helper.c
> @@ -46,34 +46,39 @@ void cpu_alpha_store_fpcr(CPUAlphaState *env, uint64_t val)
>      uint32_t fpcr = val >> 32;
>      uint32_t t = 0;
>  
> +    /* Record the raw value before adjusting for linux-user.  */
> +    env->fpcr = fpcr;
> +
> +#ifdef CONFIG_USER_ONLY
> +    /*
> +     * Override some of these bits with the contents of ENV->SWCR.
> +     * In system mode, some of these would trap to the kernel, at
> +     * 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 = 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
> -    /*
> -     * Override some of these bits with the contents of ENV->SWCR.
> -     * In system mode, some of these would trap to the kernel, at
> -     * which point the kernel's handler would emulate and apply
> -     * the software exception mask.
> -     */
>      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
>  }
>  
>
diff mbox series

Patch

diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 10602fb3394..e21c488aa32 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -46,34 +46,39 @@  void cpu_alpha_store_fpcr(CPUAlphaState *env, uint64_t val)
     uint32_t fpcr = val >> 32;
     uint32_t t = 0;
 
+    /* Record the raw value before adjusting for linux-user.  */
+    env->fpcr = fpcr;
+
+#ifdef CONFIG_USER_ONLY
+    /*
+     * Override some of these bits with the contents of ENV->SWCR.
+     * In system mode, some of these would trap to the kernel, at
+     * 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 = 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
-    /*
-     * Override some of these bits with the contents of ENV->SWCR.
-     * In system mode, some of these would trap to the kernel, at
-     * which point the kernel's handler would emulate and apply
-     * the software exception mask.
-     */
     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
 }