Patchwork [2/2] linux-user: Fix incorrect NaN detection in ARM nwfpe emulation

login
register
mail settings
Submitter Peter Maydell
Date Jan. 6, 2011, 6:34 p.m.
Message ID <1294338884-20322-3-git-send-email-peter.maydell@linaro.org>
Download mbox | patch
Permalink /patch/77792/
State New
Headers show

Comments

Peter Maydell - Jan. 6, 2011, 6:34 p.m.
The code in the linux-user ARM nwfpe emulation was incorrectly
checking only for quiet NaNs when it should have been checking
for any kind of NaN. This is probably because the code in
question was taken from the Linux kernel, whose copy of the
softfloat library had been modified so that float*_is_nan()
returned true for all NaNs, not just quiet ones. The qemu
equivalent function is float*_is_any_nan(), so use that.
NB that this code is really obsolete since nobody uses FPE
for actual arithmetic now; this is just cleanup following
the recent renaming of the NaN related functions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 linux-user/arm/nwfpe/fpa11_cprt.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
Aurelien Jarno - Jan. 7, 2011, 3:29 p.m.
On Thu, Jan 06, 2011 at 06:34:44PM +0000, Peter Maydell wrote:
> The code in the linux-user ARM nwfpe emulation was incorrectly
> checking only for quiet NaNs when it should have been checking
> for any kind of NaN. This is probably because the code in
> question was taken from the Linux kernel, whose copy of the
> softfloat library had been modified so that float*_is_nan()
> returned true for all NaNs, not just quiet ones. The qemu
> equivalent function is float*_is_any_nan(), so use that.
> NB that this code is really obsolete since nobody uses FPE
> for actual arithmetic now; this is just cleanup following
> the recent renaming of the NaN related functions.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  linux-user/arm/nwfpe/fpa11_cprt.c |   14 +++++++-------
>  1 files changed, 7 insertions(+), 7 deletions(-)

Acked-by: Aurelien Jarno <aurelien@aurel32.net>

> diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
> index 0e61b58..be54e95 100644
> --- a/linux-user/arm/nwfpe/fpa11_cprt.c
> +++ b/linux-user/arm/nwfpe/fpa11_cprt.c
> @@ -199,21 +199,21 @@ static unsigned int PerformComparison(const unsigned int opcode)
>     {
>        case typeSingle:
>          //printk("single.\n");
> -	if (float32_is_quiet_nan(fpa11->fpreg[Fn].fSingle))
> +	if (float32_is_any_nan(fpa11->fpreg[Fn].fSingle))
>  	   goto unordered;
>          rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
>        break;
>  
>        case typeDouble:
>          //printk("double.\n");
> -	if (float64_is_quiet_nan(fpa11->fpreg[Fn].fDouble))
> +	if (float64_is_any_nan(fpa11->fpreg[Fn].fDouble))
>  	   goto unordered;
>          rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
>        break;
>  
>        case typeExtended:
>          //printk("extended.\n");
> -	if (floatx80_is_quiet_nan(fpa11->fpreg[Fn].fExtended))
> +	if (floatx80_is_any_nan(fpa11->fpreg[Fn].fExtended))
>  	   goto unordered;
>          rFn = fpa11->fpreg[Fn].fExtended;
>        break;
> @@ -225,7 +225,7 @@ static unsigned int PerformComparison(const unsigned int opcode)
>     {
>       //printk("Fm is a constant: #%d.\n",Fm);
>       rFm = getExtendedConstant(Fm);
> -     if (floatx80_is_quiet_nan(rFm))
> +     if (floatx80_is_any_nan(rFm))
>          goto unordered;
>     }
>     else
> @@ -235,21 +235,21 @@ static unsigned int PerformComparison(const unsigned int opcode)
>        {
>           case typeSingle:
>             //printk("single.\n");
> -	   if (float32_is_quiet_nan(fpa11->fpreg[Fm].fSingle))
> +	   if (float32_is_any_nan(fpa11->fpreg[Fm].fSingle))
>  	      goto unordered;
>             rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
>           break;
>  
>           case typeDouble:
>             //printk("double.\n");
> -	   if (float64_is_quiet_nan(fpa11->fpreg[Fm].fDouble))
> +	   if (float64_is_any_nan(fpa11->fpreg[Fm].fDouble))
>  	      goto unordered;
>             rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
>           break;
>  
>           case typeExtended:
>             //printk("extended.\n");
> -	   if (floatx80_is_quiet_nan(fpa11->fpreg[Fm].fExtended))
> +	   if (floatx80_is_any_nan(fpa11->fpreg[Fm].fExtended))
>  	      goto unordered;
>             rFm = fpa11->fpreg[Fm].fExtended;
>           break;
> -- 
> 1.6.3.3
> 
> 
>

Patch

diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
index 0e61b58..be54e95 100644
--- a/linux-user/arm/nwfpe/fpa11_cprt.c
+++ b/linux-user/arm/nwfpe/fpa11_cprt.c
@@ -199,21 +199,21 @@  static unsigned int PerformComparison(const unsigned int opcode)
    {
       case typeSingle:
         //printk("single.\n");
-	if (float32_is_quiet_nan(fpa11->fpreg[Fn].fSingle))
+	if (float32_is_any_nan(fpa11->fpreg[Fn].fSingle))
 	   goto unordered;
         rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
       break;
 
       case typeDouble:
         //printk("double.\n");
-	if (float64_is_quiet_nan(fpa11->fpreg[Fn].fDouble))
+	if (float64_is_any_nan(fpa11->fpreg[Fn].fDouble))
 	   goto unordered;
         rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
       break;
 
       case typeExtended:
         //printk("extended.\n");
-	if (floatx80_is_quiet_nan(fpa11->fpreg[Fn].fExtended))
+	if (floatx80_is_any_nan(fpa11->fpreg[Fn].fExtended))
 	   goto unordered;
         rFn = fpa11->fpreg[Fn].fExtended;
       break;
@@ -225,7 +225,7 @@  static unsigned int PerformComparison(const unsigned int opcode)
    {
      //printk("Fm is a constant: #%d.\n",Fm);
      rFm = getExtendedConstant(Fm);
-     if (floatx80_is_quiet_nan(rFm))
+     if (floatx80_is_any_nan(rFm))
         goto unordered;
    }
    else
@@ -235,21 +235,21 @@  static unsigned int PerformComparison(const unsigned int opcode)
       {
          case typeSingle:
            //printk("single.\n");
-	   if (float32_is_quiet_nan(fpa11->fpreg[Fm].fSingle))
+	   if (float32_is_any_nan(fpa11->fpreg[Fm].fSingle))
 	      goto unordered;
            rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
          break;
 
          case typeDouble:
            //printk("double.\n");
-	   if (float64_is_quiet_nan(fpa11->fpreg[Fm].fDouble))
+	   if (float64_is_any_nan(fpa11->fpreg[Fm].fDouble))
 	      goto unordered;
            rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
          break;
 
          case typeExtended:
            //printk("extended.\n");
-	   if (floatx80_is_quiet_nan(fpa11->fpreg[Fm].fExtended))
+	   if (floatx80_is_any_nan(fpa11->fpreg[Fm].fExtended))
 	      goto unordered;
            rFm = fpa11->fpreg[Fm].fExtended;
          break;