diff mbox series

[3/7] softfloat: do not return pseudo-denormal from floatx80 remainder

Message ID alpine.DEB.2.21.2006051900130.13777@digraph.polyomino.org.uk
State New
Headers show
Series softfloat, target/i386: fprem, fprem1 fixes | expand

Commit Message

Joseph Myers June 5, 2020, 7 p.m. UTC
The floatx80 remainder implementation sometimes returns the numerator
unchanged when the denominator is sufficiently larger than the
numerator.  But if the value to be returned unchanged is a
pseudo-denormal, that is incorrect.  Fix it to normalize the numerator
in that case.

Signed-off-by: Joseph Myers <joseph@codesourcery.com>
---
 fpu/softfloat.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

Comments

Richard Henderson June 6, 2020, 7:08 p.m. UTC | #1
On 6/5/20 12:00 PM, Joseph Myers wrote:
> The floatx80 remainder implementation sometimes returns the numerator
> unchanged when the denominator is sufficiently larger than the
> numerator.  But if the value to be returned unchanged is a
> pseudo-denormal, that is incorrect.  Fix it to normalize the numerator
> in that case.
> 
> Signed-off-by: Joseph Myers <joseph@codesourcery.com>


> +        if (aExp == 0 && aSig0 >> 63) {
> +            /* Pseudo-denormal argument must be returned in normalized
> +             * form.  */
> +            return packFloatx80(aSign, 1, aSig0);

We're now standardizing on

    /*
     * muli-line
     * comment
     */

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
diff mbox series

Patch

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 091847beb9..00f362af23 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5691,7 +5691,7 @@  floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
                          float_status *status)
 {
     bool aSign, zSign;
-    int32_t aExp, bExp, expDiff;
+    int32_t aExp, bExp, expDiff, aExpOrig;
     uint64_t aSig0, aSig1, bSig;
     uint64_t q, term0, term1, alternateASig0, alternateASig1;
 
@@ -5700,7 +5700,7 @@  floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
         return floatx80_default_nan(status);
     }
     aSig0 = extractFloatx80Frac( a );
-    aExp = extractFloatx80Exp( a );
+    aExpOrig = aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
     bSig = extractFloatx80Frac( b );
     bExp = extractFloatx80Exp( b );
@@ -5715,6 +5715,11 @@  floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
         if ((uint64_t)(bSig << 1)) {
             return propagateFloatx80NaN(a, b, status);
         }
+        if (aExp == 0 && aSig0 >> 63) {
+            /* Pseudo-denormal argument must be returned in normalized
+             * form.  */
+            return packFloatx80(aSign, 1, aSig0);
+        }
         return a;
     }
     if ( bExp == 0 ) {
@@ -5734,7 +5739,14 @@  floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
     expDiff = aExp - bExp;
     aSig1 = 0;
     if ( expDiff < 0 ) {
-        if ( mod || expDiff < -1 ) return a;
+        if ( mod || expDiff < -1 ) {
+            if (aExp == 1 && aExpOrig == 0) {
+                /* Pseudo-denormal argument must be returned in
+                 * normalized form.  */
+                return packFloatx80(aSign, aExp, aSig0);
+            }
+            return a;
+        }
         shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
         expDiff = 0;
     }