Patchwork [2/2] ARM: wire up the softfloat flush_input_to_zero flag

login
register
mail settings
Submitter Peter Maydell
Date Jan. 3, 2011, 4:48 p.m.
Message ID <1294073334-2373-3-git-send-email-peter.maydell@linaro.org>
Download mbox | patch
Permalink /patch/77301/
State New
Headers show

Comments

Peter Maydell - Jan. 3, 2011, 4:48 p.m.
Wire up the new softfloat support for flushing input denormals
to zero on ARM. The FPSCR FZ bit enables flush-to-zero for
both inputs and outputs, but the reporting of when inputs are
flushed to zero is via a separate IDC bit rather than the UFC
(underflow) bit used when output denormals are flushed to zero.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)
Aurelien Jarno - Jan. 4, 2011, 3:58 p.m.
On Mon, Jan 03, 2011 at 04:48:54PM +0000, Peter Maydell wrote:
> Wire up the new softfloat support for flushing input denormals
> to zero on ARM. The FPSCR FZ bit enables flush-to-zero for
> both inputs and outputs, but the reporting of when inputs are
> flushed to zero is via a separate IDC bit rather than the UFC
> (underflow) bit used when output denormals are flushed to zero.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/helper.c |   10 ++++++++--
>  1 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 50c1017..705b99f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -2242,6 +2242,8 @@ static inline int vfp_exceptbits_from_host(int host_bits)
>          target_bits |= 8;
>      if (host_bits & float_flag_inexact)
>          target_bits |= 0x10;
> +    if (host_bits & float_flag_input_denormal)
> +        target_bits |= 0x80;
>      return target_bits;
>  }
>  
> @@ -2278,6 +2280,8 @@ static inline int vfp_exceptbits_to_host(int target_bits)
>          host_bits |= float_flag_underflow;
>      if (target_bits & 0x10)
>          host_bits |= float_flag_inexact;
> +    if (target_bits & 0x80)
> +        host_bits |= float_flag_input_denormal;
>      return host_bits;
>  }
>  
> @@ -2310,12 +2314,14 @@ void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
>          }
>          set_float_rounding_mode(i, &env->vfp.fp_status);
>      }
> -    if (changed & (1 << 24))
> +    if (changed & (1 << 24)) {
>          set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
> +        set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
> +    }
>      if (changed & (1 << 25))
>          set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
>  
> -    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
> +    i = vfp_exceptbits_to_host(val);

This change looks correct (using the flag instead of the enable bit), 
but it might be worth mentioning it.

>      set_float_exception_flags(i, &env->vfp.fp_status);
>  }

Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Peter Maydell - Jan. 4, 2011, 4:18 p.m.
On 4 January 2011 15:58, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On Mon, Jan 03, 2011 at 04:48:54PM +0000, Peter Maydell wrote:
>> -    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
>> +    i = vfp_exceptbits_to_host(val);
>
> This change looks correct (using the flag instead of the enable bit),
> but it might be worth mentioning it.

You're right, this is fixing a bug, and I did it completely by accident :-)
(all I thought I was doing was avoiding masking off the new exception
bit...)

I'll pull that change out into its own patch for v2.

-- PMM

Patch

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 50c1017..705b99f 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2242,6 +2242,8 @@  static inline int vfp_exceptbits_from_host(int host_bits)
         target_bits |= 8;
     if (host_bits & float_flag_inexact)
         target_bits |= 0x10;
+    if (host_bits & float_flag_input_denormal)
+        target_bits |= 0x80;
     return target_bits;
 }
 
@@ -2278,6 +2280,8 @@  static inline int vfp_exceptbits_to_host(int target_bits)
         host_bits |= float_flag_underflow;
     if (target_bits & 0x10)
         host_bits |= float_flag_inexact;
+    if (target_bits & 0x80)
+        host_bits |= float_flag_input_denormal;
     return host_bits;
 }
 
@@ -2310,12 +2314,14 @@  void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
         }
         set_float_rounding_mode(i, &env->vfp.fp_status);
     }
-    if (changed & (1 << 24))
+    if (changed & (1 << 24)) {
         set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
+        set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
+    }
     if (changed & (1 << 25))
         set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
 
-    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
+    i = vfp_exceptbits_to_host(val);
     set_float_exception_flags(i, &env->vfp.fp_status);
 }