qemu-devel
[Top][All Lists]
Advanced

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

[PATCH v2 4/4] softfloat: fix floatx80 pseudo-denormal round to integer


From: Joseph Myers
Subject: [PATCH v2 4/4] softfloat: fix floatx80 pseudo-denormal round to integer
Date: Mon, 4 May 2020 23:40:20 +0000
User-agent: Alpine 2.21 (DEB 202 2017-01-01)

The softfloat function floatx80_round_to_int incorrectly handles the
case of a pseudo-denormal where only the high bit of the significand
is set, ignoring that bit (treating the number as an exact zero)
rather than treating the number as an alternative representation of
+/- 2^-16382 (which may round to +/- 1 depending on the rounding mode)
as hardware does.  Fix this check (simplifying the code in the
process).

Signed-off-by: Joseph Myers <address@hidden>
---
 fpu/softfloat.c                            |  2 +-
 tests/tcg/i386/test-i386-pseudo-denormal.c | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 8e9c714e6f..e29b07542a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5741,7 +5741,7 @@ floatx80 floatx80_round_to_int(floatx80 a, float_status 
*status)
     }
     if ( aExp < 0x3FFF ) {
         if (    ( aExp == 0 )
-             && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
+             && ( (uint64_t) ( extractFloatx80Frac( a ) ) == 0 ) ) {
             return a;
         }
         status->float_exception_flags |= float_flag_inexact;
diff --git a/tests/tcg/i386/test-i386-pseudo-denormal.c 
b/tests/tcg/i386/test-i386-pseudo-denormal.c
index acf2b9cf03..00d510cf4a 100644
--- a/tests/tcg/i386/test-i386-pseudo-denormal.c
+++ b/tests/tcg/i386/test-i386-pseudo-denormal.c
@@ -14,6 +14,7 @@ volatile long double ld_res;
 
 int main(void)
 {
+    short cw;
     int ret = 0;
     ld_res = ld_pseudo_m16382.ld + ld_pseudo_m16382.ld;
     if (ld_res != 0x1p-16381L) {
@@ -24,5 +25,14 @@ int main(void)
         printf("FAIL: pseudo-denormal compare\n");
         ret = 1;
     }
+    /* Set round-upward.  */
+    __asm__ volatile ("fnstcw %0" : "=m" (cw));
+    cw = (cw & ~0xc00) | 0x800;
+    __asm__ volatile ("fldcw %0" : : "m" (cw));
+    __asm__ ("frndint" : "=t" (ld_res) : "0" (ld_pseudo_m16382.ld));
+    if (ld_res != 1.0L) {
+        printf("FAIL: pseudo-denormal round-to-integer\n");
+        ret = 1;
+    }
     return ret;
 }
-- 
2.17.1


-- 
Joseph S. Myers
address@hidden



reply via email to

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