arch-arm: Do not increment exponent if FPSCR.FZ in fplib
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 22 Apr 2020 13:50:15 +0000 (14:50 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Mon, 27 Apr 2020 13:10:45 +0000 (13:10 +0000)
If flushing to zero, the exponent shouldn't be incremented since
we are supposed to produce a 0 value and not a denormal number

Change-Id: Ib6dd594a6555b2fd9a20a52b59cbf1f5f94c2eb5
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28107
Reviewed-by: Jordi Vaquero <jordi.vaquero@metempsy.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/insts/fplib.cc

index 84ebe6d14fbdc0a620eaa90ff1531682b3c28a4e..a97943fedbcb02b1db965d26e7eb11424796bfd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2012-2013, 2017-2018 ARM Limited
+* Copyright (c) 2012-2013, 2017-2018, 2020 ARM Limited
 * Copyright (c) 2020 Metempsy Technology Consulting
 * All rights reserved
 *
@@ -393,14 +393,18 @@ fp16_unpack(int *sgn, int *exp, uint16_t *mnt, uint16_t x, int mode,
     *exp = FP16_EXP(x);
     *mnt = FP16_MANT(x);
 
-    // Handle subnormals:
     if (*exp) {
         *mnt |= 1ULL << FP16_MANT_BITS;
     } else {
-        ++*exp;
+        // Handle subnormals:
         // IDC (Input Denormal) is not set in this case.
-        if (mode & FPLIB_FZ16)
-            *mnt = 0;
+        if (*mnt) {
+            if (mode & FPLIB_FZ16) {
+                *mnt = 0;
+            } else {
+                ++*exp;
+            }
+        }
     }
 }
 
@@ -412,14 +416,17 @@ fp32_unpack(int *sgn, int *exp, uint32_t *mnt, uint32_t x, int mode,
     *exp = FP32_EXP(x);
     *mnt = FP32_MANT(x);
 
-    // Handle subnormals:
     if (*exp) {
         *mnt |= 1ULL << FP32_MANT_BITS;
     } else {
-        ++*exp;
-        if ((mode & FPLIB_FZ) && *mnt) {
-            *flags |= FPLIB_IDC;
-            *mnt = 0;
+        // Handle subnormals:
+        if (*mnt) {
+            if (mode & FPLIB_FZ) {
+                *flags |= FPLIB_IDC;
+                *mnt = 0;
+            } else {
+                ++*exp;
+            }
         }
     }
 }
@@ -434,14 +441,17 @@ fp64_unpack(int *sgn, int *exp, uint64_t *mnt, uint64_t x, int mode,
     *exp = FP64_EXP(x);
     *mnt = FP64_MANT(x);
 
-    // Handle subnormals:
     if (*exp) {
         *mnt |= 1ULL << FP64_MANT_BITS;
     } else {
-        ++*exp;
-        if ((mode & FPLIB_FZ) && *mnt) {
-            *flags |= FPLIB_IDC;
-            *mnt = 0;
+        // Handle subnormals:
+        if (*mnt) {
+            if (mode & FPLIB_FZ) {
+                *flags |= FPLIB_IDC;
+                *mnt = 0;
+            } else {
+                ++*exp;
+            }
         }
     }
 }