qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Cc: Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] [PATCH v2 06/19] softfloat: add float*_unordered_{, quiet}() functions
Date: Thu, 14 Apr 2011 01:11:01 +0200	[thread overview]
Message-ID: <1302736274-2908-7-git-send-email-aurelien@aurel32.net> (raw)
In-Reply-To: <1302736274-2908-1-git-send-email-aurelien@aurel32.net>

Add float*_unordered() functions to softfloat, matching the softfloat-native
ones. Also add float*_unordered_quiet() functions to match the others
comparison functions.

This allow target-i386/ops_sse.h to be compiled with softfloat.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c |  167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.h |    8 +++
 2 files changed, 175 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 03fb948..11f6584 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2394,6 +2394,25 @@ int float32_lt( float32 a, float32 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float32_unordered( float32 a, float32 b STATUS_PARAM )
+{
+    a = float32_squash_input_denormal(a STATUS_VAR);
+    b = float32_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+/*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
 | the corresponding value `b', and 0 otherwise.  The invalid exception is
 | raised if either operand is a NaN.  Otherwise, the comparison is performed
@@ -2481,6 +2500,29 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM )
+{
+    a = float32_squash_input_denormal(a STATUS_VAR);
+    b = float32_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+       ) {
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
+/*----------------------------------------------------------------------------
 | Returns the result of converting the double-precision floating-point value
 | `a' to the 32-bit two's complement integer format.  The conversion is
 | performed according to the IEC/IEEE Standard for Binary Floating-Point
@@ -3618,6 +3660,26 @@ int float64_lt( float64 a, float64 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float64_unordered( float64 a, float64 b STATUS_PARAM )
+{
+    a = float64_squash_input_denormal(a STATUS_VAR);
+    b = float64_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+
+/*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
 | corresponding value `b', and 0 otherwise.  The invalid exception is raised
 | if either operand is a NaN.  Otherwise, the comparison is performed
@@ -3704,6 +3766,29 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
+{
+    a = float64_squash_input_denormal(a STATUS_VAR);
+    b = float64_squash_input_denormal(b STATUS_VAR);
+
+    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+       ) {
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
@@ -4597,6 +4682,24 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point values `a' and `b'
+| cannot be compared, and 0 otherwise.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+
+/*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is equal
 | to the corresponding value `b', and 0 otherwise.  The invalid exception is
 | raised if either operand is a NaN.  Otherwise, the comparison is performed
@@ -4695,6 +4798,28 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point values `a' and `b'
+| cannot be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.
+| The comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
+         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
+              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
+       ) {
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #endif
 
 #ifdef FLOAT128
@@ -5718,6 +5843,25 @@ int float128_lt( float128 a, float128 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float128_unordered( float128 a, float128 b STATUS_PARAM )
+{
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        float_raise( float_flag_invalid STATUS_VAR);
+        return 1;
+    }
+    return 0;
+}
+
+/*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
 | the corresponding value `b', and 0 otherwise.  The invalid exception is
 | raised if either operand is a NaN.  Otherwise, the comparison is performed
@@ -5816,6 +5960,29 @@ int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
 
 }
 
+/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
+| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
+{
+    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
+              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
+         || (    ( extractFloat128Exp( b ) == 0x7FFF )
+              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
+       ) {
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return 1;
+    }
+    return 0;
+}
+
 #endif
 
 /* misc functions */
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index c7654d4..55c0c1c 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -323,9 +323,11 @@ float32 float32_log2( float32 STATUS_PARAM );
 int float32_eq( float32, float32 STATUS_PARAM );
 int float32_le( float32, float32 STATUS_PARAM );
 int float32_lt( float32, float32 STATUS_PARAM );
+int float32_unordered( float32, float32 STATUS_PARAM );
 int float32_eq_signaling( float32, float32 STATUS_PARAM );
 int float32_le_quiet( float32, float32 STATUS_PARAM );
 int float32_lt_quiet( float32, float32 STATUS_PARAM );
+int float32_unordered_quiet( float32, float32 STATUS_PARAM );
 int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 float32 float32_min(float32, float32 STATUS_PARAM);
@@ -437,9 +439,11 @@ float64 float64_log2( float64 STATUS_PARAM );
 int float64_eq( float64, float64 STATUS_PARAM );
 int float64_le( float64, float64 STATUS_PARAM );
 int float64_lt( float64, float64 STATUS_PARAM );
+int float64_unordered( float64, float64 STATUS_PARAM );
 int float64_eq_signaling( float64, float64 STATUS_PARAM );
 int float64_le_quiet( float64, float64 STATUS_PARAM );
 int float64_lt_quiet( float64, float64 STATUS_PARAM );
+int float64_unordered_quiet( float64, float64 STATUS_PARAM );
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 float64 float64_min(float64, float64 STATUS_PARAM);
@@ -538,9 +542,11 @@ floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
 int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
+int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
 int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_quiet_nan( floatx80 );
 int floatx80_is_signaling_nan( floatx80 );
 floatx80 floatx80_maybe_silence_nan( floatx80 );
@@ -621,9 +627,11 @@ float128 float128_sqrt( float128 STATUS_PARAM );
 int float128_eq( float128, float128 STATUS_PARAM );
 int float128_le( float128, float128 STATUS_PARAM );
 int float128_lt( float128, float128 STATUS_PARAM );
+int float128_unordered( float128, float128 STATUS_PARAM );
 int float128_eq_signaling( float128, float128 STATUS_PARAM );
 int float128_le_quiet( float128, float128 STATUS_PARAM );
 int float128_lt_quiet( float128, float128 STATUS_PARAM );
+int float128_unordered_quiet( float128, float128 STATUS_PARAM );
 int float128_compare( float128, float128 STATUS_PARAM );
 int float128_compare_quiet( float128, float128 STATUS_PARAM );
 int float128_is_quiet_nan( float128 );
-- 
1.7.2.3

  parent reply	other threads:[~2011-04-13 23:11 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-13 23:10 [Qemu-devel] [PATCH v2 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
2011-04-13 23:10 ` [Qemu-devel] [PATCH v2 01/19] softfloat: use GCC builtins to count the leading zeros Aurelien Jarno
2011-04-13 23:10 ` [Qemu-devel] [PATCH v2 02/19] cpu-all.h: define CPU_LDoubleU Aurelien Jarno
2011-04-13 23:10 ` [Qemu-devel] [PATCH v2 03/19] target-i386: use CPU_LDoubleU instead of a private union Aurelien Jarno
2011-04-13 23:10 ` [Qemu-devel] [PATCH v2 04/19] target-i386: use float unions from cpu-all.h Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 05/19] target-i386: add floatx_{add, mul, sub} and use them Aurelien Jarno
2011-04-13 23:11 ` Aurelien Jarno [this message]
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 07/19] softfloat-native: add float*_unordered_quiet() functions Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 08/19] target-alpha: use new float64_unordered_quiet() function Aurelien Jarno
2011-04-14 16:35   ` Richard Henderson
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 09/19] target-mips: use new float*_unordered*() functions Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 10/19] target-i386: fix CMPUNORDPS/D and CMPORDPS/D instructions Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 11/19] softfloat: rename float*_eq() into float*_eq_quiet() Aurelien Jarno
2011-04-14  8:54   ` Edgar E. Iglesias
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 12/19] softfloat: rename float*_eq_signaling() into float*_eq() Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 13/19] softfloat: move float*_eq and float*_eq_quiet Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 14/19] softfloat: improve description of comparison functions Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 15/19] target-ppc: fix SPE " Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 16/19] target-mips: simplify FP comparisons Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 17/19] target-mips: don't hardcode softfloat exception bits Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 18/19] target-mips: fix c.ps.* instructions Aurelien Jarno
2011-04-13 23:11 ` [Qemu-devel] [PATCH v2 19/19] target-mips: clear softfpu exception state for comparison instructions Aurelien Jarno

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1302736274-2908-7-git-send-email-aurelien@aurel32.net \
    --to=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).