diff mbox

fpu: add mechanism to check for invalid long double formats

Message ID 1471059185-18108-1-git-send-email-andrew@andrewdutcher.com
State New
Headers show

Commit Message

Andrew Dutcher Aug. 13, 2016, 3:33 a.m. UTC
The macro require_valid_floatx80(value, status) will check for malformed
extended precision encodings, and if one is found, generate an
invalid-operation exception and return NaN. This check has been added to
the beginning of the basic 80-bit float arithmetic functions.

Signed-off-by: Andrew Dutcher <andrew@andrewdutcher.com>
---
 fpu/softfloat-specialize.h | 12 ++++++++++++
 fpu/softfloat.c            | 11 +++++++++++
 include/fpu/softfloat.h    | 12 ++++++++++++
 3 files changed, 35 insertions(+)

Comments

no-reply@patchew.org Aug. 13, 2016, 2:17 p.m. UTC | #1
Hi,

Your series seems to have some coding style problems. See output below for
more information:

Message-id: 1471059185-18108-1-git-send-email-andrew@andrewdutcher.com
Subject: [Qemu-devel] [PATCH] fpu: add mechanism to check for invalid long double formats
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/1471059185-18108-1-git-send-email-andrew@andrewdutcher.com -> patchew/1471059185-18108-1-git-send-email-andrew@andrewdutcher.com
Switched to a new branch 'test'
69805da fpu: add mechanism to check for invalid long double formats

=== OUTPUT BEGIN ===
Checking PATCH 1/1: fpu: add mechanism to check for invalid long double formats...
ERROR: open brace '{' following function declarations go on the next line
#108: FILE: include/fpu/softfloat.h:680:
+static inline bool floatx80_invalid_encoding(floatx80 a) {

total: 1 errors, 0 warnings, 83 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
diff mbox

Patch

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 43d0890..0e6ec25 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -203,6 +203,18 @@  void float_raise(int8_t flags, float_status *status)
 }
 
 /*----------------------------------------------------------------------------
+| Asserts that the given value must be a valid floatx80 encoding. If The given
+| value is a pseudo-NaN, pseudo-infiinty, or un-normal, raise an invalid
+| operation exception and cause the parent function to return NaN.
+*----------------------------------------------------------------------------*/
+
+#define require_valid_floatx80(a, status)           \
+    if (floatx80_invalid_encoding((a))) {               \
+        float_raise(float_flag_invalid, (status));        \
+        return floatx80_default_nan((status));            \
+    }
+
+/*----------------------------------------------------------------------------
 | Internal canonical NaN format.
 *----------------------------------------------------------------------------*/
 typedef struct {
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9b1eccf..a921e5e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5279,6 +5279,8 @@  floatx80 floatx80_add(floatx80 a, floatx80 b, float_status *status)
 {
     flag aSign, bSign;
 
+    require_valid_floatx80(a, status);
+    require_valid_floatx80(b, status);
     aSign = extractFloatx80Sign( a );
     bSign = extractFloatx80Sign( b );
     if ( aSign == bSign ) {
@@ -5300,6 +5302,8 @@  floatx80 floatx80_sub(floatx80 a, floatx80 b, float_status *status)
 {
     flag aSign, bSign;
 
+    require_valid_floatx80(a, status);
+    require_valid_floatx80(b, status);
     aSign = extractFloatx80Sign( a );
     bSign = extractFloatx80Sign( b );
     if ( aSign == bSign ) {
@@ -5323,6 +5327,8 @@  floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
     int32_t aExp, bExp, zExp;
     uint64_t aSig, bSig, zSig0, zSig1;
 
+    require_valid_floatx80(a, status);
+    require_valid_floatx80(b, status);
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
@@ -5380,6 +5386,8 @@  floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
     uint64_t aSig, bSig, zSig0, zSig1;
     uint64_t rem0, rem1, rem2, term0, term1, term2;
 
+    require_valid_floatx80(a, status);
+    require_valid_floatx80(b, status);
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
@@ -5461,6 +5469,8 @@  floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
     uint64_t aSig0, aSig1, bSig;
     uint64_t q, term0, term1, alternateASig0, alternateASig1;
 
+    require_valid_floatx80(a, status);
+    require_valid_floatx80(b, status);
     aSig0 = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
@@ -5556,6 +5566,7 @@  floatx80 floatx80_sqrt(floatx80 a, float_status *status)
     uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
 
+    require_valid_floatx80(a, status);
     aSig0 = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 0e57ee5..cf703ef 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -671,6 +671,18 @@  static inline int floatx80_is_any_nan(floatx80 a)
 floatx80 floatx80_default_nan(float_status *status);
 
 /*----------------------------------------------------------------------------
+| Return whether the given value is an invalid floatx80 encoding.
+| Invalid floatx80 encodings arise when the integer bit is not set, but
+| the exponent is not zero. The only times the integer bit is permitted to
+| be zero is in subnormal numbers and the value zero.
+*----------------------------------------------------------------------------*/
+
+static inline bool floatx80_invalid_encoding(floatx80 a) {
+    return !(a.low & 0x8000000000000000) && !!(a.high & 0x7FFF);
+}
+
+
+/*----------------------------------------------------------------------------
 | Software IEC/IEEE quadruple-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int32_t float128_to_int32(float128, float_status *status);