qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [6107] Implement flush-to-zero mode ( denormal results are


From: Paul Brook
Subject: [Qemu-devel] [6107] Implement flush-to-zero mode ( denormal results are replaced with zero).
Date: Fri, 19 Dec 2008 14:33:59 +0000

Revision: 6107
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6107
Author:   pbrook
Date:     2008-12-19 14:33:59 +0000 (Fri, 19 Dec 2008)

Log Message:
-----------
Implement flush-to-zero mode (denormal results are replaced with zero).

Signed-off-by: Paul Brook <address@hidden>

Modified Paths:
--------------
    trunk/fpu/softfloat.c
    trunk/fpu/softfloat.h
    trunk/target-arm/helper.c

Modified: trunk/fpu/softfloat.c
===================================================================
--- trunk/fpu/softfloat.c       2008-12-19 13:53:37 UTC (rev 6106)
+++ trunk/fpu/softfloat.c       2008-12-19 14:33:59 UTC (rev 6107)
@@ -30,6 +30,8 @@
 
 =============================================================================*/
 
+/* FIXME: Flush-To-Zero only effects results.  Denormal inputs should also
+   be flushed to zero.  */
 #include "softfloat.h"
 
 /*----------------------------------------------------------------------------
@@ -294,6 +296,7 @@
             return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
         }
         if ( zExp < 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
             isTiny =
                    ( STATUS(float_detect_tininess) == 
float_tininess_before_rounding )
                 || ( zExp < -1 )
@@ -457,6 +460,7 @@
             return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
         }
         if ( zExp < 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
             isTiny =
                    ( STATUS(float_detect_tininess) == 
float_tininess_before_rounding )
                 || ( zExp < -1 )
@@ -635,6 +639,7 @@
             goto overflow;
         }
         if ( zExp <= 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 );
             isTiny =
                    ( STATUS(float_detect_tininess) == 
float_tininess_before_rounding )
                 || ( zExp < 0 )
@@ -965,6 +970,7 @@
             return packFloat128( zSign, 0x7FFF, 0, 0 );
         }
         if ( zExp < 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
             isTiny =
                    ( STATUS(float_detect_tininess) == 
float_tininess_before_rounding )
                 || ( zExp < -1 )
@@ -1637,7 +1643,10 @@
             if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
             return a;
         }
-        if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
+        if ( aExp == 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );
+            return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
+        }
         zSig = 0x40000000 + aSig + bSig;
         zExp = aExp;
         goto roundAndPack;
@@ -2595,7 +2604,10 @@
             if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
             return a;
         }
-        if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
+        if ( aExp == 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
+            return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
+        }
         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
         zExp = aExp;
         goto roundAndPack;
@@ -4597,7 +4609,10 @@
             return a;
         }
         add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
-        if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
+        if ( aExp == 0 ) {
+            if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
+            return packFloat128( zSign, 0, zSig0, zSig1 );
+        }
         zSig2 = 0;
         zSig0 |= LIT64( 0x0002000000000000 );
         zExp = aExp;

Modified: trunk/fpu/softfloat.h
===================================================================
--- trunk/fpu/softfloat.h       2008-12-19 13:53:37 UTC (rev 6106)
+++ trunk/fpu/softfloat.h       2008-12-19 14:33:59 UTC (rev 6107)
@@ -190,11 +190,16 @@
 #ifdef FLOATX80
     signed char floatx80_rounding_precision;
 #endif
+    flag flush_to_zero;
     flag default_nan_mode;
 } float_status;
 
 void set_float_rounding_mode(int val STATUS_PARAM);
 void set_float_exception_flags(int val STATUS_PARAM);
+INLINE void set_flush_to_zero(flag val STATUS_PARAM)
+{
+    STATUS(flush_to_zero) = val;
+}
 INLINE void set_default_nan_mode(flag val STATUS_PARAM)
 {
     STATUS(default_nan_mode) = val;

Modified: trunk/target-arm/helper.c
===================================================================
--- trunk/target-arm/helper.c   2008-12-19 13:53:37 UTC (rev 6106)
+++ trunk/target-arm/helper.c   2008-12-19 14:33:59 UTC (rev 6107)
@@ -2334,12 +2334,13 @@
         }
         set_float_rounding_mode(i, &env->vfp.fp_status);
     }
+    if (changed & (1 << 24))
+        set_flush_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);
     set_float_exception_flags(i, &env->vfp.fp_status);
-    /* XXX: FZ and DN are not implemented.  */
 }
 
 #define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))






reply via email to

[Prev in Thread] Current Thread [Next in Thread]