qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements
@ 2011-04-12 21:59 Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 01/19] softfloat: use GCC builtins to count the leading zeros Aurelien Jarno
                   ` (19 more replies)
  0 siblings, 20 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel

This patch series started with the goal of improving the build of
target-i386 with softfloat (instead of softfloat-native), but it slowly
became a collection of fixes and improvements with regard to softfloat 
and targets FPU.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 01/19] softfloat: use GCC builtins to count the leading zeros
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 02/19] cpu-all.h: define CPU_LDoubleU Aurelien Jarno
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Aurelien Jarno

Softfloat has its own implementation to count the leading zeros. However
a lot of architectures have either a dedicated instruction or an
optimized to do that. When using GCC >= 3.4, this patch uses GCC builtins
instead of the handcoded implementation.

Note that I amware that QEMU_GNUC_PREREQ is defined in osdep.h and that
clz32() and clz64() are defined in host-utils.h, but I think it is better
to keep the softfloat implemntation self contained.

Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-macros.h |   29 +++++++++++++++++++++++++++--
 1 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
index 3128e60..e82ce23 100644
--- a/fpu/softfloat-macros.h
+++ b/fpu/softfloat-macros.h
@@ -36,6 +36,17 @@ these four paragraphs for those parts of this code that are retained.
 =============================================================================*/
 
 /*----------------------------------------------------------------------------
+| This macro tests for minimum version of the GNU C compiler.
+*----------------------------------------------------------------------------*/
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define SOFTFLOAT_GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define SOFTFLOAT_GNUC_PREREQ(maj, min) 0
+#endif
+
+
+/*----------------------------------------------------------------------------
 | Shifts `a' right by the number of bits given in `count'.  If any nonzero
 | bits are shifted off, they are ``jammed'' into the least significant bit of
 | the result by setting the least significant bit to 1.  The value of `count'
@@ -616,6 +627,13 @@ static uint32_t estimateSqrt32( int16 aExp, uint32_t a )
 
 static int8 countLeadingZeros32( uint32_t a )
 {
+#if SOFTFLOAT_GNUC_PREREQ(3, 4)
+    if (a) {
+        return __builtin_clz(a);
+    } else {
+        return 32;
+    }
+#else
     static const int8 countLeadingZerosHigh[] = {
         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -647,7 +665,7 @@ static int8 countLeadingZeros32( uint32_t a )
     }
     shiftCount += countLeadingZerosHigh[ a>>24 ];
     return shiftCount;
-
+#endif
 }
 
 /*----------------------------------------------------------------------------
@@ -657,6 +675,13 @@ static int8 countLeadingZeros32( uint32_t a )
 
 static int8 countLeadingZeros64( uint64_t a )
 {
+#if SOFTFLOAT_GNUC_PREREQ(3, 4)
+    if (a) {
+        return __builtin_clzll(a);
+    } else {
+        return 64;
+    }
+#else
     int8 shiftCount;
 
     shiftCount = 0;
@@ -668,7 +693,7 @@ static int8 countLeadingZeros64( uint64_t a )
     }
     shiftCount += countLeadingZeros32( a );
     return shiftCount;
-
+#endif
 }
 
 /*----------------------------------------------------------------------------
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 02/19] cpu-all.h: define CPU_LDoubleU
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 01/19] softfloat: use GCC builtins to count the leading zeros Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 03/19] target-i386: use CPU_LDoubleU instead of a private union Aurelien Jarno
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, Aurelien Jarno

Add a CPU_LDoubleU type, matching the floatx80 definition and the long
double type on x86 hosts.

Based on a patch from Laurent Vivier <laurent@vivier.eu>.

Cc: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 cpu-all.h |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index dc0f2f0..0bae6df 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -138,6 +138,16 @@ typedef union {
     uint64_t ll;
 } CPU_DoubleU;
 
+#if defined(FLOATX80)
+typedef union {
+     floatx80 d;
+     struct {
+         uint64_t lower;
+         uint16_t upper;
+     } l;
+} CPU_LDoubleU;
+#endif
+
 #if defined(CONFIG_SOFTFLOAT)
 typedef union {
     float128 q;
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 03/19] target-i386: use CPU_LDoubleU instead of a private union
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 01/19] softfloat: use GCC builtins to count the leading zeros Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 02/19] cpu-all.h: define CPU_LDoubleU Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 04/19] target-i386: use float unions from cpu-all.h Aurelien Jarno
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, Aurelien Jarno

Use CPU_LDoubleU in cpu_dump_state() instead of redefining a union for
doing the conversion.

Based on a patch from Laurent Vivier <laurent@vivier.eu>.

Cc: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/helper.c |   12 +++---------
 1 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index d15fca5..89df997 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -404,16 +404,10 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     env->mxcsr);
         for(i=0;i<8;i++) {
 #if defined(USE_X86LDOUBLE)
-            union {
-                long double d;
-                struct {
-                    uint64_t lower;
-                    uint16_t upper;
-                } l;
-            } tmp;
-            tmp.d = env->fpregs[i].d;
+            CPU_LDoubleU u;
+            u.d = env->fpregs[i].d;
             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
-                        i, tmp.l.lower, tmp.l.upper);
+                        i, u.l.lower, u.l.upper);
 #else
             cpu_fprintf(f, "FPR%d=%016" PRIx64,
                         i, env->fpregs[i].mmx.q);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 04/19] target-i386: use float unions from cpu-all.h
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (2 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 03/19] target-i386: use CPU_LDoubleU instead of a private union Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 05/19] target-i386: add floatx_{add, mul, sub} and use them Aurelien Jarno
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Use float unions from cpu-all.h instead of redefining new (wrong for arm)
ones in target-i386. This also allows building cpu-exec.o with softfloat.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h |   27 ++-------------------------
 1 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 6f9f709..63a23cd 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -144,13 +144,7 @@ static inline void svm_check_intercept(uint32_t type)
 #ifdef USE_X86LDOUBLE
 
 /* only for x86 */
-typedef union {
-    long double d;
-    struct {
-        unsigned long long lower;
-        unsigned short upper;
-    } l;
-} CPU86_LDoubleU;
+typedef CPU_LDoubleU CPU86_LDoubleU;
 
 /* the following deal with x86 long double-precision numbers */
 #define MAXEXPD 0x7fff
@@ -162,24 +156,7 @@ typedef union {
 
 #else
 
-/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
-typedef union {
-    double d;
-#if !defined(HOST_WORDS_BIGENDIAN) && !defined(__arm__)
-    struct {
-        uint32_t lower;
-        int32_t upper;
-    } l;
-#else
-    struct {
-        int32_t upper;
-        uint32_t lower;
-    } l;
-#endif
-#ifndef __arm__
-    int64_t ll;
-#endif
-} CPU86_LDoubleU;
+typedef CPU_DoubleU CPU86_LDoubleU;
 
 /* the following deal with IEEE double-precision numbers */
 #define MAXEXPD 0x7ff
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 05/19] target-i386: add floatx_{add, mul, sub} and use them
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (3 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 04/19] target-i386: use float unions from cpu-all.h Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 06/19] softfloat: add float*_unordered_{, quiet}() functions Aurelien Jarno
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add floatx_{add,mul,sub} defines, and use them instead of using direct
C operations.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/exec.h      |    6 ++++++
 target-i386/op_helper.c |   18 ++++++++----------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 63a23cd..ae6b947 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -110,6 +110,9 @@ static inline void svm_check_intercept(uint32_t type)
 #define float64_to_floatx float64_to_floatx80
 #define floatx_to_float32 floatx80_to_float32
 #define floatx_to_float64 floatx80_to_float64
+#define floatx_add floatx80_add
+#define floatx_mul floatx80_mul
+#define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
 #define floatx_round_to_int floatx80_round_to_int
@@ -126,6 +129,9 @@ static inline void svm_check_intercept(uint32_t type)
 #define float64_to_floatx(x, e) (x)
 #define floatx_to_float32 float64_to_float32
 #define floatx_to_float64(x, e) (x)
+#define floatx_add float64_add
+#define floatx_mul float64_mul
+#define floatx_sub float64_sub
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
 #define floatx_round_to_int float64_round_to_int
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 43fbd0c..a73427f 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3711,22 +3711,22 @@ void helper_fucomi_ST0_FT0(void)
 
 void helper_fadd_ST0_FT0(void)
 {
-    ST0 += FT0;
+    ST0 = floatx_add(ST0, FT0, &env->fp_status);
 }
 
 void helper_fmul_ST0_FT0(void)
 {
-    ST0 *= FT0;
+    ST0 = floatx_mul(ST0, FT0, &env->fp_status);
 }
 
 void helper_fsub_ST0_FT0(void)
 {
-    ST0 -= FT0;
+    ST0 = floatx_sub(ST0, FT0, &env->fp_status);
 }
 
 void helper_fsubr_ST0_FT0(void)
 {
-    ST0 = FT0 - ST0;
+    ST0 = floatx_sub(FT0, ST0, &env->fp_status);
 }
 
 void helper_fdiv_ST0_FT0(void)
@@ -3743,24 +3743,22 @@ void helper_fdivr_ST0_FT0(void)
 
 void helper_fadd_STN_ST0(int st_index)
 {
-    ST(st_index) += ST0;
+    ST(st_index) = floatx_add(ST(st_index), ST0, &env->fp_status);
 }
 
 void helper_fmul_STN_ST0(int st_index)
 {
-    ST(st_index) *= ST0;
+    ST(st_index) = floatx_mul(ST(st_index), ST0, &env->fp_status);
 }
 
 void helper_fsub_STN_ST0(int st_index)
 {
-    ST(st_index) -= ST0;
+    ST(st_index) = floatx_sub(ST(st_index), ST0, &env->fp_status);
 }
 
 void helper_fsubr_STN_ST0(int st_index)
 {
-    CPU86_LDouble *p;
-    p = &ST(st_index);
-    *p = ST0 - *p;
+    ST(st_index) = floatx_sub(ST0, ST(st_index), &env->fp_status);
 }
 
 void helper_fdiv_STN_ST0(int st_index)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 06/19] softfloat: add float*_unordered_{, quiet}() functions
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (4 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 05/19] target-i386: add floatx_{add, mul, sub} and use them Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 07/19] softfloat-native: add float*_unordered_quiet() functions Aurelien Jarno
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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.

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

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 07/19] softfloat-native: add float*_unordered_quiet() functions
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (5 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 06/19] softfloat: add float*_unordered_{, quiet}() functions Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function Aurelien Jarno
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add float*_unordered_quiet() functions to march the softfloat versions.
As FPU status is not tracked with softfloat-native, they don't differ
from the signaling version.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 80b5f28..406e180 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -237,7 +237,10 @@ INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
 INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
 {
     return isunordered(a, b);
-
+}
+INLINE int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM)
+{
+    return isunordered(a, b);
 }
 int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
@@ -346,7 +349,10 @@ INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
 INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
 {
     return isunordered(a, b);
-
+}
+INLINE int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM)
+{
+    return isunordered(a, b);
 }
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
@@ -450,7 +456,10 @@ INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
 INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return isunordered(a, b);
-
+}
+INLINE int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM)
+{
+    return isunordered(a, b);
 }
 int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (6 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 07/19] softfloat-native: add float*_unordered_quiet() functions Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-13 14:52   ` Peter Maydell
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 09/19] target-mips: use new float*_unordered*() functions Aurelien Jarno
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Use float64_unordered() in helper_cmptun() instead of doing the
the comparison manually. This also fixes the wrong behaviours with
sNaNs.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-alpha/op_helper.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 6c2ae20..e07ae69 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -904,10 +904,11 @@ uint64_t helper_cmptun (uint64_t a, uint64_t b)
     fa = t_to_float64(a);
     fb = t_to_float64(b);
 
-    if (float64_is_quiet_nan(fa) || float64_is_quiet_nan(fb))
+    if (float64_unordered(fa, fb, &FP_STATUS)) {
         return 0x4000000000000000ULL;
-    else
+    } else {
         return 0;
+    }
 }
 
 uint64_t helper_cmpteq(uint64_t a, uint64_t b)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 09/19] target-mips: use new float*_unordered*() functions
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (7 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 10/19] target-i386: fix CMPUNORDPS/D and CMPORDPS/D instructions Aurelien Jarno
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Use the new float*_unordered*() functions from softfloat instead of
redefining a private version.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c |  168 ++++++++++++++++++++---------------------------
 1 files changed, 70 insertions(+), 98 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index bd16ce3..e9de692 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2889,40 +2889,26 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
         CLEAR_FP_COND(cc, env->active_fpu);                    \
 }
 
-static int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
-{
-    if (float64_is_signaling_nan(a) ||
-        float64_is_signaling_nan(b) ||
-        (sig && (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)))) {
-        float_raise(float_flag_invalid, status);
-        return 1;
-    } else if (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_D(f,   (float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status), 0))
-FOP_COND_D(un,  float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq,  !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ * but float64_unordered_quiet() is still called. */
+FOP_COND_D(f,   (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(un,  float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(olt, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ole, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_D(sf,  (float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status), 0))
-FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(lt,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(le,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ * but float64_unordered() is still called. */
+FOP_COND_D(sf,  (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(lt,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(le,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 
 #define FOP_COND_S(op, cond)                                   \
 void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
@@ -2947,40 +2933,26 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
         CLEAR_FP_COND(cc, env->active_fpu);                    \
 }
 
-static flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
-{
-    if (float32_is_signaling_nan(a) ||
-        float32_is_signaling_nan(b) ||
-        (sig && (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)))) {
-        float_raise(float_flag_invalid, status);
-        return 1;
-    } else if (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_S(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0))
-FOP_COND_S(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ * but float32_unordered_quiet() is still called. */
+FOP_COND_S(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_S(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0))
-FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ * but float32_unordered() is still called. */
+FOP_COND_S(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 
 #define FOP_COND_PS(op, condl, condh)                           \
 void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
@@ -3023,38 +2995,38 @@ void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
 }
 
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_PS(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0),
-                 (float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status), 0))
-FOP_COND_PS(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+ * but float32_unordered_quiet() is still called. */
+FOP_COND_PS(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0),
+                 (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
- * but float*_is_unordered() is still called. */
-FOP_COND_PS(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0),
-                 (float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status), 0))
-FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+ * but float32_unordered() is still called. */
+FOP_COND_PS(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
+                 (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 10/19] target-i386: fix CMPUNORDPS/D and CMPORDPS/D instructions
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (8 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 09/19] target-mips: use new float*_unordered*() functions Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 11/19] softfloat: rename float*_eq() into float*_eq_quiet() Aurelien Jarno
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

SSE instructions CMPUNORDPS/D and CMPORDPS/D do not trigger an invalid
exception if operands are qNANs.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/ops_sse.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index 3232abd..986cbe3 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -924,11 +924,11 @@ void helper_ ## name ## sd (Reg *d, Reg *s)\
 #define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
-#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0
+#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? - 1 : 0
 #define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
-#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
+#define FPU_CMPORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? 0 : -1
 
 SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
 SSE_HELPER_CMP(cmplt, FPU_CMPLT)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 11/19] softfloat: rename float*_eq() into float*_eq_quiet()
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (9 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 10/19] target-i386: fix CMPUNORDPS/D and CMPORDPS/D instructions Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 12/19] softfloat: rename float*_eq_signaling() into float*_eq() Aurelien Jarno
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexander Graf, Aurelien Jarno, Edgar E. Iglesias

float*_eq functions have a different semantics than other comparison
functions. Fix that by first renaming float*_quiet() into float*_eq_quiet().

Note that it is purely mechanical, and the behaviour should be unchanged.
That said it clearly highlight problems due to this different semantics,
they are fixed later in this patch series.

Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Cc: Alexander Graf <agraf@suse.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h            |    6 +++---
 fpu/softfloat.c                   |    8 ++++----
 fpu/softfloat.h                   |    8 ++++----
 linux-user/arm/nwfpe/fpa11_cprt.c |    2 +-
 target-alpha/op_helper.c          |    4 ++--
 target-i386/ops_sse.h             |    8 ++++----
 target-microblaze/op_helper.c     |    4 ++--
 target-mips/op_helper.c           |   32 ++++++++++++++++----------------
 target-ppc/op_helper.c            |    4 ++--
 9 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 406e180..0c7f48b 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -210,7 +210,7 @@ INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
 }
 float32 float32_rem( float32, float32  STATUS_PARAM);
 float32 float32_sqrt( float32  STATUS_PARAM);
-INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
+INLINE int float32_eq_quiet( float32 a, float32 b STATUS_PARAM)
 {
     return a == b;
 }
@@ -321,7 +321,7 @@ INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
 }
 float64 float64_rem( float64, float64 STATUS_PARAM );
 float64 float64_sqrt( float64 STATUS_PARAM );
-INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
+INLINE int float64_eq_quiet( float64 a, float64 b STATUS_PARAM)
 {
     return a == b;
 }
@@ -428,7 +428,7 @@ INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
 }
 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
+INLINE int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return a == b;
 }
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 11f6584..492ef36 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2318,7 +2318,7 @@ float32 float32_log2( float32 a STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq( float32 a, float32 b STATUS_PARAM )
+int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
 {
     a = float32_squash_input_denormal(a STATUS_VAR);
     b = float32_squash_input_denormal(b STATUS_VAR);
@@ -3582,7 +3582,7 @@ float64 float64_log2( float64 a STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq( float64 a, float64 b STATUS_PARAM )
+int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -4592,7 +4592,7 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
 | Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -5754,7 +5754,7 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq( float128 a, float128 b STATUS_PARAM )
+int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 55c0c1c..738a50c 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -320,7 +320,7 @@ float32 float32_rem( float32, float32 STATUS_PARAM );
 float32 float32_sqrt( float32 STATUS_PARAM );
 float32 float32_exp2( float32 STATUS_PARAM );
 float32 float32_log2( float32 STATUS_PARAM );
-int float32_eq( float32, float32 STATUS_PARAM );
+int float32_eq_quiet( 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 );
@@ -436,7 +436,7 @@ float64 float64_div( float64, float64 STATUS_PARAM );
 float64 float64_rem( float64, float64 STATUS_PARAM );
 float64 float64_sqrt( float64 STATUS_PARAM );
 float64 float64_log2( float64 STATUS_PARAM );
-int float64_eq( float64, float64 STATUS_PARAM );
+int float64_eq_quiet( 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 );
@@ -539,7 +539,7 @@ floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq_quiet( 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 );
@@ -624,7 +624,7 @@ float128 float128_mul( float128, float128 STATUS_PARAM );
 float128 float128_div( float128, float128 STATUS_PARAM );
 float128 float128_rem( float128, float128 STATUS_PARAM );
 float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq( float128, float128 STATUS_PARAM );
+int float128_eq_quiet( 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 );
diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
index be54e95..8011897 100644
--- a/linux-user/arm/nwfpe/fpa11_cprt.c
+++ b/linux-user/arm/nwfpe/fpa11_cprt.c
@@ -159,7 +159,7 @@ PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
    }
 
    /* test for equal condition */
-   if (floatx80_eq(Fn,Fm, &fpa11->fp_status))
+   if (floatx80_eq_quiet(Fn,Fm, &fpa11->fp_status))
    {
       flags |= CC_ZERO;
    }
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index e07ae69..bc938ed 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -918,7 +918,7 @@ uint64_t helper_cmpteq(uint64_t a, uint64_t b)
     fa = t_to_float64(a);
     fb = t_to_float64(b);
 
-    if (float64_eq(fa, fb, &FP_STATUS))
+    if (float64_eq_quiet(fa, fb, &FP_STATUS))
         return 0x4000000000000000ULL;
     else
         return 0;
@@ -957,7 +957,7 @@ uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
     fa = g_to_float64(a);
     fb = g_to_float64(b);
 
-    if (float64_eq(fa, fb, &FP_STATUS))
+    if (float64_eq_quiet(fa, fb, &FP_STATUS))
         return 0x4000000000000000ULL;
     else
         return 0;
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index 986cbe3..ac0f150 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -921,11 +921,11 @@ void helper_ ## name ## sd (Reg *d, Reg *s)\
     d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
 }
 
-#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0
+#define FPU_CMPEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0
 #define FPU_CMPUNORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? - 1 : 0
-#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1
+#define FPU_CMPNEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1
 #define FPU_CMPORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? 0 : -1
@@ -1216,8 +1216,8 @@ void helper_pfadd(MMXReg *d, MMXReg *s)
 
 void helper_pfcmpeq(MMXReg *d, MMXReg *s)
 {
-    d->MMX_L(0) = float32_eq(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0;
-    d->MMX_L(1) = float32_eq(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0;
+    d->MMX_L(0) = float32_eq_quiet(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0;
+    d->MMX_L(1) = float32_eq_quiet(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0;
 }
 
 void helper_pfcmpge(MMXReg *d, MMXReg *s)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 39b8ec1..b7cd6b2 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -338,7 +338,7 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
     set_float_exception_flags(0, &env->fp_status);
     fa.l = a;
     fb.l = b;
-    r = float32_eq(fa.f, fb.f, &env->fp_status);
+    r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
     update_fpu_flags(flags & float_flag_invalid);
 
@@ -384,7 +384,7 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
     fa.l = a;
     fb.l = b;
     set_float_exception_flags(0, &env->fp_status);
-    r = !float32_eq(fa.f, fb.f, &env->fp_status);
+    r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
     flags = get_float_exception_flags(&env->fp_status);
     update_fpu_flags(flags & float_flag_invalid);
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index e9de692..31a19ba 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2893,8 +2893,8 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
  * but float64_unordered_quiet() is still called. */
 FOP_COND_D(f,   (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(un,  float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(olt, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ole, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
@@ -2903,8 +2903,8 @@ FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)
  * but float64_unordered() is still called. */
 FOP_COND_D(sf,  (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(lt,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(le,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
@@ -2937,8 +2937,8 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
  * but float32_unordered_quiet() is still called. */
 FOP_COND_S(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
@@ -2947,8 +2947,8 @@ FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)
  * but float32_unordered() is still called. */
 FOP_COND_S(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
@@ -3000,10 +3000,10 @@ FOP_COND_PS(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status
                  (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
                  !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
@@ -3018,10 +3018,10 @@ FOP_COND_PS(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
                  (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
                  !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 4dae464..f645f57 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3352,7 +3352,7 @@ static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
     CPU_FloatU u1, u2;
     u1.l = op1;
     u2.l = op2;
-    return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0;
+    return float32_eq_quiet(u1.f, u2.f, &env->vec_status) ? 4 : 0;
 }
 
 static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
@@ -3666,7 +3666,7 @@ uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2)
     CPU_DoubleU u1, u2;
     u1.ll = op1;
     u2.ll = op2;
-    return float64_eq(u1.d, u2.d, &env->vec_status) ? 4 : 0;
+    return float64_eq_quiet(u1.d, u2.d, &env->vec_status) ? 4 : 0;
 }
 
 uint32_t helper_efdcmplt (uint64_t op1, uint64_t op2)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 12/19] softfloat: rename float*_eq_signaling() into float*_eq()
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (10 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 11/19] softfloat: rename float*_eq() into float*_eq_quiet() Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 13/19] softfloat: move float*_eq and float*_eq_quiet Aurelien Jarno
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

float*_eq_signaling functions have a different semantics than other
comparison functions. Fix that by renaming float*_quiet_signaling() into
float*_eq().

Note that it is purely mechanical, and the behaviour should be unchanged.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-native.h |    6 +++---
 fpu/softfloat.c        |    8 ++++----
 fpu/softfloat.h        |    8 ++++----
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 0c7f48b..ea7a15e 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -222,7 +222,7 @@ INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
 {
     return a < b;
 }
-INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
+INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
 {
     return a <= b && a >= b;
 }
@@ -333,7 +333,7 @@ INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
 {
     return a < b;
 }
-INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
+INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
 {
     return a <= b && a >= b;
 }
@@ -440,7 +440,7 @@ INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return a < b;
 }
-INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
+INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
 {
     return a <= b && a >= b;
 }
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 492ef36..2e02940 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2419,7 +2419,7 @@ int float32_unordered( float32 a, float32 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
+int float32_eq( float32 a, float32 b STATUS_PARAM )
 {
     uint32_t av, bv;
     a = float32_squash_input_denormal(a STATUS_VAR);
@@ -3686,7 +3686,7 @@ int float64_unordered( float64 a, float64 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
+int float64_eq( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -4706,7 +4706,7 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -5868,7 +5868,7 @@ int float128_unordered( float128 a, float128 b STATUS_PARAM )
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
+int float128_eq( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 738a50c..b9440b2 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -324,7 +324,7 @@ int float32_eq_quiet( 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_eq( 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 );
@@ -440,7 +440,7 @@ int float64_eq_quiet( 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_eq( 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 );
@@ -543,7 +543,7 @@ int floatx80_eq_quiet( 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_eq( 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 );
@@ -628,7 +628,7 @@ int float128_eq_quiet( 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_eq( 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 );
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 13/19] softfloat: move float*_eq and float*_eq_quiet
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (11 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 12/19] softfloat: rename float*_eq_signaling() into float*_eq() Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 14/19] softfloat: improve description of comparison functions Aurelien Jarno
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

I am not a big fan of code moving, but having the signaling version in
the middle of quiet versions and vice versa doesn't make the code easy
to read.

This patch is a simple code move, basically swapping locations of
float*_eq and float*_eq_quiet.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c |  101 +++++++++++++++++++++++++++----------------------------
 fpu/softfloat.h |   16 ++++----
 2 files changed, 58 insertions(+), 59 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 2e02940..efd718b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2314,26 +2314,26 @@ float32 float32_log2( float32 a STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  Otherwise, the comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
+int float32_eq( float32 a, float32 b STATUS_PARAM )
 {
+    uint32_t av, bv;
     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);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
-    return ( float32_val(a) == float32_val(b) ) ||
-            ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
-
+    av = float32_val(a);
+    bv = float32_val(b);
+    return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
 }
 
 /*----------------------------------------------------------------------------
@@ -2412,29 +2412,28 @@ int float32_unordered( float32 a, float32 b STATUS_PARAM )
     }
     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
+| the corresponding value `b', and 0 otherwise.  The comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float32_eq( float32 a, float32 b STATUS_PARAM )
+int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
 {
-    uint32_t av, bv;
     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);
+        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
-    av = float32_val(a);
-    bv = float32_val(b);
-    return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
-
+    return ( float32_val(a) == float32_val(b) ) ||
+            ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
 }
 
 /*----------------------------------------------------------------------------
@@ -3578,11 +3577,12 @@ float64 float64_log2( float64 a STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise.  The comparison is performed
+| corresponding value `b', and 0 otherwise.  The invalid exception is raised
+| if either operand is a NaN.  Otherwise, the comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
+int float64_eq( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -3591,9 +3591,7 @@ int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
     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);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
     av = float64_val(a);
@@ -3681,12 +3679,11 @@ int float64_unordered( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | 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
+| corresponding value `b', and 0 otherwise.  The comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float64_eq( float64 a, float64 b STATUS_PARAM )
+int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
 {
     uint64_t av, bv;
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -3695,7 +3692,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
     av = float64_val(a);
@@ -4586,13 +4585,13 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise.  The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| 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
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -4600,10 +4599,7 @@ int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
          || (    ( 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);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
     return
@@ -4700,13 +4696,13 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 }
 
 /*----------------------------------------------------------------------------
-| 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
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| Returns 1 if the extended double-precision floating-point value `a' is
+| equal to the corresponding value `b', and 0 otherwise.  The comparison is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
+int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
@@ -4714,7 +4710,10 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if (    floatx80_is_signaling_nan( a )
+             || floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
     return
@@ -5750,11 +5749,12 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  Otherwise, the comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
+int float128_eq( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
@@ -5762,10 +5762,7 @@ int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
          || (    ( 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);
-        }
+        float_raise( float_flag_invalid STATUS_VAR);
         return 0;
     }
     return
@@ -5863,12 +5860,11 @@ int float128_unordered( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | 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
+| the corresponding value `b', and 0 otherwise.  The comparison is performed
 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-int float128_eq( float128 a, float128 b STATUS_PARAM )
+int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
 {
 
     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
@@ -5876,7 +5872,10 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
          || (    ( extractFloat128Exp( b ) == 0x7FFF )
               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
        ) {
-        float_raise( float_flag_invalid STATUS_VAR);
+        if (    float128_is_signaling_nan( a )
+             || float128_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
         return 0;
     }
     return
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index b9440b2..340f0a9 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -320,11 +320,11 @@ float32 float32_rem( float32, float32 STATUS_PARAM );
 float32 float32_sqrt( float32 STATUS_PARAM );
 float32 float32_exp2( float32 STATUS_PARAM );
 float32 float32_log2( float32 STATUS_PARAM );
-int float32_eq_quiet( float32, 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( float32, float32 STATUS_PARAM );
+int float32_eq_quiet( 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 );
@@ -436,11 +436,11 @@ float64 float64_div( float64, float64 STATUS_PARAM );
 float64 float64_rem( float64, float64 STATUS_PARAM );
 float64 float64_sqrt( float64 STATUS_PARAM );
 float64 float64_log2( float64 STATUS_PARAM );
-int float64_eq_quiet( float64, 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( float64, float64 STATUS_PARAM );
+int float64_eq_quiet( 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 );
@@ -539,11 +539,11 @@ floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq_quiet( floatx80, 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( floatx80, floatx80 STATUS_PARAM );
+int floatx80_eq_quiet( 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 );
@@ -624,11 +624,11 @@ float128 float128_mul( float128, float128 STATUS_PARAM );
 float128 float128_div( float128, float128 STATUS_PARAM );
 float128 float128_rem( float128, float128 STATUS_PARAM );
 float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq_quiet( float128, 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( float128, float128 STATUS_PARAM );
+int float128_eq_quiet( 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 );
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 14/19] softfloat: improve description of comparison functions
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (12 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 13/19] softfloat: move float*_eq and float*_eq_quiet Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet() Aurelien Jarno
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Make clear for all comparison functions which ones trigger an exception
for all NaNs, and which one only for sNaNs.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat.c |   85 +++++++++++++++++++++++++++++++------------------------
 1 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index efd718b..6ce0b61 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2338,9 +2338,9 @@ int float32_eq( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise.  The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| or equal to the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_le( float32 a, float32 b STATUS_PARAM )
@@ -2367,8 +2367,9 @@ int float32_le( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_lt( float32 a, float32 b STATUS_PARAM )
@@ -2395,8 +2396,9 @@ 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.
+| be compared, and 0 otherwise.  The invalid exception is raised if either
+| operand is a NaN.  The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float32_unordered( float32 a, float32 b STATUS_PARAM )
@@ -2415,8 +2417,9 @@ int float32_unordered( float32 a, float32 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', 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_eq_quiet( float32 a, float32 b STATUS_PARAM )
@@ -3602,9 +3605,9 @@ int float64_eq( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise.  The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| equal to the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_le( float64 a, float64 b STATUS_PARAM )
@@ -3631,8 +3634,9 @@ int float64_le( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_lt( float64 a, float64 b STATUS_PARAM )
@@ -3659,8 +3663,9 @@ 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.
+| be compared, and 0 otherwise.  The invalid exception is raised if either
+| operand is a NaN.  The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float64_unordered( float64 a, float64 b STATUS_PARAM )
@@ -3679,8 +3684,9 @@ int float64_unordered( float64 a, float64 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| corresponding value `b', 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_eq_quiet( float64 a, float64 b STATUS_PARAM )
@@ -4614,8 +4620,9 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is
 | less than or equal to the corresponding value `b', and 0 otherwise.  The
-| comparison is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
+| invalid exception is raised if either operand is a NaN.  The comparison is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4646,9 +4653,9 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is
-| less than the corresponding value `b', and 0 otherwise.  The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| less than the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
@@ -4679,8 +4686,9 @@ 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.
+| cannot be compared, and 0 otherwise.  The invalid exception is raised if
+| either operand is a NaN.   The comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 {
@@ -4697,9 +4705,9 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise.  The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| equal to the corresponding value `b', 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_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
@@ -5776,9 +5784,9 @@ int float128_eq( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise.  The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
+| or equal to the corresponding value `b', and 0 otherwise.  The invalid
+| exception is raised if either operand is a NaN.  The comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_le( float128 a, float128 b STATUS_PARAM )
@@ -5809,8 +5817,9 @@ int float128_le( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', and 0 otherwise.  The invalid exception is
+| raised if either operand is a NaN.  The comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_lt( float128 a, float128 b STATUS_PARAM )
@@ -5841,8 +5850,9 @@ 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.
+| be compared, and 0 otherwise.  The invalid exception is raised if either
+| operand is a NaN. The comparison is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
 int float128_unordered( float128 a, float128 b STATUS_PARAM )
@@ -5860,8 +5870,9 @@ int float128_unordered( float128 a, float128 b STATUS_PARAM )
 
 /*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise.  The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| the corresponding value `b', 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_eq_quiet( float128 a, float128 b STATUS_PARAM )
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet()
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (13 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 14/19] softfloat: improve description of comparison functions Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 22:41   ` Peter Maydell
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 16/19] target-alpha: fix wrong usage of float64_eq_quiet() Aurelien Jarno
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Aurelien Jarno

I haven't look at the documentation, but for the neighbouring code it looks
clear that floatx80_eq() should be used instead of floatx80_eq_quiet().

Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 linux-user/arm/nwfpe/fpa11_cprt.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
index 8011897..be54e95 100644
--- a/linux-user/arm/nwfpe/fpa11_cprt.c
+++ b/linux-user/arm/nwfpe/fpa11_cprt.c
@@ -159,7 +159,7 @@ PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
    }
 
    /* test for equal condition */
-   if (floatx80_eq_quiet(Fn,Fm, &fpa11->fp_status))
+   if (floatx80_eq(Fn,Fm, &fpa11->fp_status))
    {
       flags |= CC_ZERO;
    }
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 16/19] target-alpha: fix wrong usage of float64_eq_quiet()
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (14 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet() Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-13 15:15   ` Peter Maydell
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions Aurelien Jarno
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

On alpha, all NaN should trap during a comparison, not only sNaN. Fix
this by using float64_eq() instead of float64_eq_quiet().

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 64990e0735007f75fe03123c1339366bcb496268)
---
 target-alpha/op_helper.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index bc938ed..b986b67 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -918,10 +918,11 @@ uint64_t helper_cmpteq(uint64_t a, uint64_t b)
     fa = t_to_float64(a);
     fb = t_to_float64(b);
 
-    if (float64_eq_quiet(fa, fb, &FP_STATUS))
+    if (float64_eq(fa, fb, &FP_STATUS)) {
         return 0x4000000000000000ULL;
-    else
+    } else {
         return 0;
+    }
 }
 
 uint64_t helper_cmptle(uint64_t a, uint64_t b)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (15 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 16/19] target-alpha: fix wrong usage of float64_eq_quiet() Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-13  2:40   ` Nathan Froyd
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 18/19] target-mips: simplify FP comparisons Aurelien Jarno
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Nathan Froyd, Alexander Graf, Aurelien Jarno

efstst*() functions are fast SPE funtions which do not take into account
special values (infinites, NaN, etc.), while efscmp*() functions are
IEEE754 compliant.

Given that float32_*() functions are IEEE754 compliant, the efscmp*()
functions are correctly implemented, while efstst*() are not. This
patch reverse the implementation of this two groups of functions and
fix the comments. It also use float32_eq() instead of float32_eq_quiet()
as qNaNs should not be ignored.

Cc: Alexander Graf <agraf@suse.de>
Cc: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 9f4055a7d1426c6a1f6b11725e3458ada4cbc5eb)
---
 target-ppc/op_helper.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index f645f57..696958a 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3331,7 +3331,7 @@ HELPER_SPE_VECTOR_ARITH(fsmul);
 HELPER_SPE_VECTOR_ARITH(fsdiv);
 
 /* Single-precision floating-point comparisons */
-static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
 {
     CPU_FloatU u1, u2;
     u1.l = op1;
@@ -3339,7 +3339,7 @@ static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
     return float32_lt(u1.f, u2.f, &env->vec_status) ? 4 : 0;
 }
 
-static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2)
 {
     CPU_FloatU u1, u2;
     u1.l = op1;
@@ -3347,29 +3347,29 @@ static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
     return float32_le(u1.f, u2.f, &env->vec_status) ? 0 : 4;
 }
 
-static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
+static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2)
 {
     CPU_FloatU u1, u2;
     u1.l = op1;
     u2.l = op2;
-    return float32_eq_quiet(u1.f, u2.f, &env->vec_status) ? 4 : 0;
+    return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0;
 }
 
-static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
+static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
 {
-    /* XXX: TODO: test special values (NaN, infinites, ...) */
+    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
     return efststlt(op1, op2);
 }
 
-static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2)
+static inline uint32_t efststgt(uint32_t op1, uint32_t op2)
 {
-    /* XXX: TODO: test special values (NaN, infinites, ...) */
+    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
     return efststgt(op1, op2);
 }
 
-static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2)
+static inline uint32_t efststeq(uint32_t op1, uint32_t op2)
 {
-    /* XXX: TODO: test special values (NaN, infinites, ...) */
+    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
     return efststeq(op1, op2);
 }
 
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 18/19] target-mips: simplify FP comparisons
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (16 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 19/19] target-mips: don't hardcode softfloat exception bits Aurelien Jarno
  2011-04-13 15:45 ` [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Peter Maydell
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

As the softfloat comparison functions already test for NaN, there is no
need to always call the float*_unordered*() functions.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c |   72 +++++++++++++++++++++++-----------------------
 1 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 31a19ba..abcb6eb 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2893,21 +2893,21 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
  * but float64_unordered_quiet() is still called. */
 FOP_COND_D(f,   (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(un,  float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(eq,  !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(olt, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ole, !float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float64_unordered() is still called. */
 FOP_COND_D(sf,  (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0))
 FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))
-FOP_COND_D(seq, !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(lt,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(seq, float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(lt,  float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
-FOP_COND_D(le,  !float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(le,  float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 
 #define FOP_COND_S(op, cond)                                   \
@@ -2937,21 +2937,21 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
  * but float32_unordered_quiet() is still called. */
 FOP_COND_S(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)  || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float32_unordered() is still called. */
 FOP_COND_S(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0))
 FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status))
-FOP_COND_S(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(lt,  float32_lt(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
-FOP_COND_S(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(le,  float32_le(fst0, fst1, &env->active_fpu.fp_status))
 FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 
 #define FOP_COND_PS(op, condl, condh)                           \
@@ -3000,33 +3000,33 @@ FOP_COND_PS(f,   (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status
                  (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(un,  float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(eq,  !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(olt, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ole, !float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)    || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float32_unordered() is still called. */
 FOP_COND_PS(sf,  (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0),
                  (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0))
 FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status))
-FOP_COND_PS(seq, !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status),
-                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(lt,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(lt,  float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
-FOP_COND_PS(le,  !float32_unordered(fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
-                 !float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(le,  float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
 FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
                  float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH 19/19] target-mips: don't hardcode softfloat exception bits
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (17 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 18/19] target-mips: simplify FP comparisons Aurelien Jarno
@ 2011-04-12 21:59 ` Aurelien Jarno
  2011-04-13 15:45 ` [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Peter Maydell
  19 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-12 21:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/op_helper.c |   35 ++++++++++++++++++++---------------
 1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index abcb6eb..0a62361 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2077,22 +2077,27 @@ void helper_ctc1 (target_ulong arg1, uint32_t reg)
         helper_raise_exception(EXCP_FPE);
 }
 
-static inline char ieee_ex_to_mips(char xcpt)
+static inline int ieee_ex_to_mips(int xcpt)
 {
-    return (xcpt & float_flag_inexact) >> 5 |
-           (xcpt & float_flag_underflow) >> 3 |
-           (xcpt & float_flag_overflow) >> 1 |
-           (xcpt & float_flag_divbyzero) << 1 |
-           (xcpt & float_flag_invalid) << 4;
-}
-
-static inline char mips_ex_to_ieee(char xcpt)
-{
-    return (xcpt & FP_INEXACT) << 5 |
-           (xcpt & FP_UNDERFLOW) << 3 |
-           (xcpt & FP_OVERFLOW) << 1 |
-           (xcpt & FP_DIV0) >> 1 |
-           (xcpt & FP_INVALID) >> 4;
+    int ret = 0;
+    if (xcpt) {
+        if (xcpt & float_flag_invalid) {
+            ret |= FP_INVALID;
+        }
+        if (xcpt & float_flag_overflow) {
+            ret |= FP_OVERFLOW;
+        }
+        if (xcpt & float_flag_underflow) {
+            ret |= FP_UNDERFLOW;
+        }
+        if (xcpt & float_flag_divbyzero) {
+            ret |= FP_DIV0;
+        }
+        if (xcpt & float_flag_inexact) {
+            ret |= FP_INEXACT;
+        }
+    }
+    return ret;
 }
 
 static inline void update_fcr31(void)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet()
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet() Aurelien Jarno
@ 2011-04-12 22:41   ` Peter Maydell
  2011-04-13 18:11     ` Aurelien Jarno
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2011-04-12 22:41 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 12 April 2011 22:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> I haven't look at the documentation, but for the neighbouring code it looks
> clear that floatx80_eq() should be used instead of floatx80_eq_quiet().

Actually I think it's irrelevant -- PerformComparisonOperation()
is called only once, and the code before it carefully checks for
any NaNs and takes a different code path in that case (jumping
to the 'unordered' label). So it doesn't matter which function
we use here. I don't particularly object if you think using the
non _quiet one is aesthetically tidier. (The nwfpe code is all
hovering on the edge of total obsolescence anyhow; I certainly
don't have any test cases for it.)

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions Aurelien Jarno
@ 2011-04-13  2:40   ` Nathan Froyd
  2011-04-13 18:11     ` Aurelien Jarno
  0 siblings, 1 reply; 37+ messages in thread
From: Nathan Froyd @ 2011-04-13  2:40 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel, Alexander Graf

On Tue, Apr 12, 2011 at 11:59:29PM +0200, Aurelien Jarno wrote:
> Given that float32_*() functions are IEEE754 compliant, the efscmp*()
> functions are correctly implemented, while efstst*() are not. This
> patch reverse the implementation of this two groups of functions and
> fix the comments. It also use float32_eq() instead of float32_eq_quiet()
> as qNaNs should not be ignored.

Thanks for addressing this; the E500 emulation in QEMU is more like how
we wish the hardware acted, rather than how it actually acts. :)

It's late here, but I think this change:

> -static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
> +static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
>  {
> -    /* XXX: TODO: test special values (NaN, infinites, ...) */
> +    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
>      return efststlt(op1, op2);
>  }

is not correct, as you've just turned this into an infinite (inlined!)
loop.  You'd want to change the efststlt call into an efscmplt call.
Similarly for efstst{gt,eq}.

-Nathan

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function Aurelien Jarno
@ 2011-04-13 14:52   ` Peter Maydell
  2011-04-13 15:38     ` Richard Henderson
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2011-04-13 14:52 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 12 April 2011 22:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Use float64_unordered() in helper_cmptun() instead of doing the
> the comparison manually. This also fixes the wrong behaviours with
> sNaNs.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-alpha/op_helper.c |    5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
> index 6c2ae20..e07ae69 100644
> --- a/target-alpha/op_helper.c
> +++ b/target-alpha/op_helper.c
> @@ -904,10 +904,11 @@ uint64_t helper_cmptun (uint64_t a, uint64_t b)
>     fa = t_to_float64(a);
>     fb = t_to_float64(b);
>
> -    if (float64_is_quiet_nan(fa) || float64_is_quiet_nan(fb))
> +    if (float64_unordered(fa, fb, &FP_STATUS)) {
>         return 0x4000000000000000ULL;
> -    else
> +    } else {
>         return 0;
> +    }
>  }

I'm not sure this is right. The Alpha Architecture Handbook is a
bit opaque, but the Compiler Writer's Guide is clearer:
www.compaq.com/cpq-alphaserver/technology/literature/cmpwrgd.pdf
page D-4 says that CMPTUN (like CMPTEQ) should generate InvalidOp
for SNaNs but not for QNaNs. (Contrast CMPTLT, CMPTLE, which set
InvalidOp for both SNaNs and QNaNs.)

So I think you want the _quiet version here. (And helper_cmpteq
needs to use float64_eq_quiet rather than float64_eq.)

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 16/19] target-alpha: fix wrong usage of float64_eq_quiet()
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 16/19] target-alpha: fix wrong usage of float64_eq_quiet() Aurelien Jarno
@ 2011-04-13 15:15   ` Peter Maydell
  0 siblings, 0 replies; 37+ messages in thread
From: Peter Maydell @ 2011-04-13 15:15 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 12 April 2011 22:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On alpha, all NaN should trap during a comparison, not only sNaN. Fix
> this by using float64_eq() instead of float64_eq_quiet().

The Compiler Writer's Guide disagrees with you:
www.compaq.com/cpq-alphaserver/technology/literature/cmpwrgd.pdf
page D-4 says CMPTEQ and CMPTUN only raise InvalidOp for SNaN.
(the Architecture Handbook is a little less clear but I think
the equivalent table is pages B-8 and B-9).

So I think this patch which changes helper_cmpteq() isn't needed.

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-13 14:52   ` Peter Maydell
@ 2011-04-13 15:38     ` Richard Henderson
  2011-04-13 15:42       ` Peter Maydell
  2011-04-14  9:14       ` Peter Maydell
  0 siblings, 2 replies; 37+ messages in thread
From: Richard Henderson @ 2011-04-13 15:38 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Aurelien Jarno

[ Odd, the original thread doesn't seem to have arrived here. ]

On 04/13/2011 07:52 AM, Peter Maydell wrote:
> So I think you want the _quiet version here. (And helper_cmpteq
> needs to use float64_eq_quiet rather than float64_eq.)

Yes, the _quiet version is what's needed for all comparisons.

For the record, the goal for QEMU should not be to emulate the
hardware exactly, but to emulate the entire HW+OS system.  Thus
when looking at Table B-2 one should look at the OS Completion
Handler and User Signal Handler columns.

That's for /s qualified instructions anyway.  For non-ieee code
we take care to inject the extra traps via helper_ieee_input*.

(It looks like some of the Alpha code can be cleaned up a bit.
I don't recall flush_inputs_to_zero option being there before,
and we do that by hand in helper_ieee_input*.)


r~

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-13 15:38     ` Richard Henderson
@ 2011-04-13 15:42       ` Peter Maydell
  2011-04-13 15:53         ` Richard Henderson
  2011-04-14  9:14       ` Peter Maydell
  1 sibling, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2011-04-13 15:42 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Aurelien Jarno

On 13 April 2011 16:38, Richard Henderson <rth@twiddle.net> wrote:
> [ Odd, the original thread doesn't seem to have arrived here. ]
>
> On 04/13/2011 07:52 AM, Peter Maydell wrote:
>> So I think you want the _quiet version here. (And helper_cmpteq
>> needs to use float64_eq_quiet rather than float64_eq.)
>
> Yes, the _quiet version is what's needed for all comparisons.

Really all comparisons, including CMPTLT, CMPTLE?

> (It looks like some of the Alpha code can be cleaned up a bit.
> I don't recall flush_inputs_to_zero option being there before,
> and we do that by hand in helper_ieee_input*.)

Yes, I added that softfloat feature for the benefit of ARM's
flush-to-zero mode.

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements
  2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
                   ` (18 preceding siblings ...)
  2011-04-12 21:59 ` [Qemu-devel] [PATCH 19/19] target-mips: don't hardcode softfloat exception bits Aurelien Jarno
@ 2011-04-13 15:45 ` Peter Maydell
  19 siblings, 0 replies; 37+ messages in thread
From: Peter Maydell @ 2011-04-13 15:45 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 12 April 2011 22:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> This patch series started with the goal of improving the build of
> target-i386 with softfloat (instead of softfloat-native), but it slowly
> became a collection of fixes and improvements with regard to softfloat
> and targets FPU.

For patches 01 02 03 04 05 06 07 09 10 11 12 13 14 18 19
[but not 08 15 16 17]:

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-13 15:42       ` Peter Maydell
@ 2011-04-13 15:53         ` Richard Henderson
  2011-04-13 18:18           ` Aurelien Jarno
  0 siblings, 1 reply; 37+ messages in thread
From: Richard Henderson @ 2011-04-13 15:53 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Aurelien Jarno

On 04/13/2011 08:42 AM, Peter Maydell wrote:
> On 13 April 2011 16:38, Richard Henderson <rth@twiddle.net> wrote:
>> [ Odd, the original thread doesn't seem to have arrived here. ]
>>
>> On 04/13/2011 07:52 AM, Peter Maydell wrote:
>>> So I think you want the _quiet version here. (And helper_cmpteq
>>> needs to use float64_eq_quiet rather than float64_eq.)
>>
>> Yes, the _quiet version is what's needed for all comparisons.
> 
> Really all comparisons, including CMPTLT, CMPTLE?

Oops, no.  CMPTLE and CMPTLT in Table B-2 are on the next page,
and clearly indicate that they signal InvalidOP for QNaN.

So it's just CMPTUN and CMPTEQ that should not signal on QNaN.


r~

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet()
  2011-04-12 22:41   ` Peter Maydell
@ 2011-04-13 18:11     ` Aurelien Jarno
  0 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-13 18:11 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 12, 2011 at 11:41:49PM +0100, Peter Maydell wrote:
> On 12 April 2011 22:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > I haven't look at the documentation, but for the neighbouring code it looks
> > clear that floatx80_eq() should be used instead of floatx80_eq_quiet().
> 
> Actually I think it's irrelevant -- PerformComparisonOperation()
> is called only once, and the code before it carefully checks for
> any NaNs and takes a different code path in that case (jumping
> to the 'unordered' label). So it doesn't matter which function
> we use here. I don't particularly object if you think using the
> non _quiet one is aesthetically tidier. (The nwfpe code is all
> hovering on the edge of total obsolescence anyhow; I certainly
> don't have any test cases for it.)
> 

Ok, I will simply drop it then.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions
  2011-04-13  2:40   ` Nathan Froyd
@ 2011-04-13 18:11     ` Aurelien Jarno
  0 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-13 18:11 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: qemu-devel, Alexander Graf

On Tue, Apr 12, 2011 at 07:40:33PM -0700, Nathan Froyd wrote:
> On Tue, Apr 12, 2011 at 11:59:29PM +0200, Aurelien Jarno wrote:
> > Given that float32_*() functions are IEEE754 compliant, the efscmp*()
> > functions are correctly implemented, while efstst*() are not. This
> > patch reverse the implementation of this two groups of functions and
> > fix the comments. It also use float32_eq() instead of float32_eq_quiet()
> > as qNaNs should not be ignored.
> 
> Thanks for addressing this; the E500 emulation in QEMU is more like how
> we wish the hardware acted, rather than how it actually acts. :)
> 
> It's late here, but I think this change:
> 
> > -static inline uint32_t efscmplt(uint32_t op1, uint32_t op2)
> > +static inline uint32_t efststlt(uint32_t op1, uint32_t op2)
> >  {
> > -    /* XXX: TODO: test special values (NaN, infinites, ...) */
> > +    /* XXX: TODO: ignore special values (NaN, infinites, ...) */
> >      return efststlt(op1, op2);
> >  }
> 
> is not correct, as you've just turned this into an infinite (inlined!)
> loop.  You'd want to change the efststlt call into an efscmplt call.
> Similarly for efstst{gt,eq}.
> 

Thanks for catching that, I'll fix that in the next version.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-13 15:53         ` Richard Henderson
@ 2011-04-13 18:18           ` Aurelien Jarno
  0 siblings, 0 replies; 37+ messages in thread
From: Aurelien Jarno @ 2011-04-13 18:18 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Peter Maydell, qemu-devel

On Wed, Apr 13, 2011 at 08:53:27AM -0700, Richard Henderson wrote:
> On 04/13/2011 08:42 AM, Peter Maydell wrote:
> > On 13 April 2011 16:38, Richard Henderson <rth@twiddle.net> wrote:
> >> [ Odd, the original thread doesn't seem to have arrived here. ]
> >>
> >> On 04/13/2011 07:52 AM, Peter Maydell wrote:
> >>> So I think you want the _quiet version here. (And helper_cmpteq
> >>> needs to use float64_eq_quiet rather than float64_eq.)
> >>
> >> Yes, the _quiet version is what's needed for all comparisons.
> > 
> > Really all comparisons, including CMPTLT, CMPTLE?
> 
> Oops, no.  CMPTLE and CMPTLT in Table B-2 are on the next page,
> and clearly indicate that they signal InvalidOP for QNaN.
> 
> So it's just CMPTUN and CMPTEQ that should not signal on QNaN.
> 

Thanks to both of you for digging into the manuals, the information I
have found in the manual I have were not so clear. I'll fix that in the
next version.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-13 15:38     ` Richard Henderson
  2011-04-13 15:42       ` Peter Maydell
@ 2011-04-14  9:14       ` Peter Maydell
  2011-04-14 15:14         ` Richard Henderson
  1 sibling, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2011-04-14  9:14 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Aurelien Jarno

On 13 April 2011 16:38, Richard Henderson <rth@twiddle.net> wrote:
> (It looks like some of the Alpha code can be cleaned up a bit.
> I don't recall flush_inputs_to_zero option being there before,
> and we do that by hand in helper_ieee_input*.)

While we're on the subject of Alpha and flush-to-zero modes,
do you know what exception bits should get set when Alpha
flushes a denormal output (not input) to zero?

At the moment softfloat doesn't set any flags when it does
this, which is definitely wrong for ARM. I had a look at
the manuals for the other archs which might set flush_to_zero:

 SH: should set underflow flag
 ARM: should set underflow flag
 PPC: should set underflow (I think)
 MIPS: docs didn't say

I think Alpha should set Inexact and not Underflow, but
I'm not sure -- can you confirm/deny?

(Obviously I would prefer it if every architecture just
needed to set underflow, but somehow I don't think it
will work out that cleanly :-))

thanks
-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-14  9:14       ` Peter Maydell
@ 2011-04-14 15:14         ` Richard Henderson
  2011-04-14 15:39           ` Peter Maydell
  0 siblings, 1 reply; 37+ messages in thread
From: Richard Henderson @ 2011-04-14 15:14 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Aurelien Jarno

On 04/14/2011 02:14 AM, Peter Maydell wrote:
> While we're on the subject of Alpha and flush-to-zero modes,
> do you know what exception bits should get set when Alpha
> flushes a denormal output (not input) to zero?
...
> I think Alpha should set Inexact and not Underflow, but
> I'm not sure -- can you confirm/deny?

Deny.

Page B-8, Add Sub Output Exceptions,

  Exponent underflow and disabled:
    Supply +0, no exception delivered to user.

  Exponent underflow and enabled:
    Supply +-MIN denorm, Underflow delivered to user.

    Footnote 3, Overflow and Underflow have priority over Inexact.


r~

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-14 15:14         ` Richard Henderson
@ 2011-04-14 15:39           ` Peter Maydell
  2011-04-14 16:27             ` Richard Henderson
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2011-04-14 15:39 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Aurelien Jarno

On 14 April 2011 16:14, Richard Henderson <rth@twiddle.net> wrote:
> On 04/14/2011 02:14 AM, Peter Maydell wrote:
>> While we're on the subject of Alpha and flush-to-zero modes,
>> do you know what exception bits should get set when Alpha
>> flushes a denormal output (not input) to zero?
> ...
>> I think Alpha should set Inexact and not Underflow, but
>> I'm not sure -- can you confirm/deny?
>
> Deny.
>
> Page B-8, Add Sub Output Exceptions,
>
>  Exponent underflow and disabled:
>    Supply +0, no exception delivered to user.
>
>  Exponent underflow and enabled:
>    Supply +-MIN denorm, Underflow delivered to user.
>
>    Footnote 3, Overflow and Underflow have priority over Inexact.

Thanks. Does "no exception delivered to user" mean also
"and do not set FPCR bit UNF" ?

The reason I thought it might set Inexact is that I was looking
at page 4-79, which says:

"If both the UNFD (underflow disable) bit and the UNDZ (underflow
 to zero) bit are set in the FPCR, the implementation sets the
 result of an underflow operation to a true zero result. The
 zeroing of a denormal result by UNDZ must also be treated as an
 inexact result."

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-14 15:39           ` Peter Maydell
@ 2011-04-14 16:27             ` Richard Henderson
  2011-04-14 16:48               ` Peter Maydell
  0 siblings, 1 reply; 37+ messages in thread
From: Richard Henderson @ 2011-04-14 16:27 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Aurelien Jarno

On 04/14/2011 08:39 AM, Peter Maydell wrote:
>>  Exponent underflow and disabled:
>>    Supply +0, no exception delivered to user.
>>
>>  Exponent underflow and enabled:
>>    Supply +-MIN denorm, Underflow delivered to user.
>>
>>    Footnote 3, Overflow and Underflow have priority over Inexact.
> 
> Thanks. Does "no exception delivered to user" mean also
> "and do not set FPCR bit UNF" ?

Yes.

> The reason I thought it might set Inexact is that I was looking
> at page 4-79, which says:
> 
> "If both the UNFD (underflow disable) bit and the UNDZ (underflow
>  to zero) bit are set in the FPCR, the implementation sets the
>  result of an underflow operation to a true zero result. The
>  zeroing of a denormal result by UNDZ must also be treated as an
>  inexact result."

Hum.  It looks like we can choose between these results then,
depending on the intersection of the FPCR disable bits, and
the per-instruction trapping mode bits (see section 4.7.7.2).

I *think* what would be best for Alpha is if, within softfloat,
both conditions are signaled, and then we can filter the result
that is actually needed via helper_fp_exc_raise?  It's hard to
say without actually doing the work...

Unfortunately, I suspect that the Correct result on real HW
also depends on the OS completion handler, and I know that at
least for Linux that code was written before UNDZ was added.
So I don't know if even real HW produces the correct result
when considering Underflow priority over Inexact.


r~

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-14 16:27             ` Richard Henderson
@ 2011-04-14 16:48               ` Peter Maydell
  2011-04-14 17:01                 ` Richard Henderson
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2011-04-14 16:48 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Aurelien Jarno

On 14 April 2011 17:27, Richard Henderson <rth@twiddle.net> wrote:
> On 04/14/2011 08:39 AM, Peter Maydell wrote:
>>>  Exponent underflow and disabled:
>>>    Supply +0, no exception delivered to user.
>>>
>>>  Exponent underflow and enabled:
>>>    Supply +-MIN denorm, Underflow delivered to user.
>>>
>>>    Footnote 3, Overflow and Underflow have priority over Inexact.
>>
>> Thanks. Does "no exception delivered to user" mean also
>> "and do not set FPCR bit UNF" ?
>
> Yes.
>
>> The reason I thought it might set Inexact is that I was looking
>> at page 4-79, which says:
>>
>> "If both the UNFD (underflow disable) bit and the UNDZ (underflow
>>  to zero) bit are set in the FPCR, the implementation sets the
>>  result of an underflow operation to a true zero result. The
>>  zeroing of a denormal result by UNDZ must also be treated as an
>>  inexact result."
>
> Hum.  It looks like we can choose between these results then,
> depending on the intersection of the FPCR disable bits, and
> the per-instruction trapping mode bits (see section 4.7.7.2).
>
> I *think* what would be best for Alpha is if, within softfloat,
> both conditions are signaled, and then we can filter the result
> that is actually needed via helper_fp_exc_raise?  It's hard to
> say without actually doing the work...

Unfortunately doing that is bad for other architectures because
they tend to let the softfloat status flags act directly as
the cumulative exception flags, so if softfloat sets flags they
don't want you've suddenly imposed a burden of saving and
restoring flags or something similarly ugly.

It sounds like maybe what we need is to have a
 signed char float_ftz_flags
or similar in float_status which should be set to the
float_flags which should be passed to float_raise() when
we flush an output denormal to zero. Then we can set that to
float_flag_underflow for ARM, leave it at 0 for other
architectures [preserve existing semantics] and set it to
float_flag_underflow | float_flag_inexact for Alpha.

Or the other approach would be to do something like
how the 'denormal-input-went-to-zero' case is handled: have
an extra float_flag for float_flag_output_denormal, and let
targets either (a) special-case it or (b) merge it with
whichever of underflow or inexact they like when constructing
the guest-visible floating point status flags. I kind of like
that better, actually.

-- PMM

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function
  2011-04-14 16:48               ` Peter Maydell
@ 2011-04-14 17:01                 ` Richard Henderson
  0 siblings, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2011-04-14 17:01 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Aurelien Jarno

On 04/14/2011 09:48 AM, Peter Maydell wrote:
> Or the other approach would be to do something like
> how the 'denormal-input-went-to-zero' case is handled: have
> an extra float_flag for float_flag_output_denormal, and let
> targets either (a) special-case it or (b) merge it with
> whichever of underflow or inexact they like when constructing
> the guest-visible floating point status flags. I kind of like
> that better, actually.

Either of your proposed solutions works for me.

Either allows significant freedom in the backend to decide on
how to implement the per-instruction selection.


r~

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2011-04-14 17:02 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-12 21:59 [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 01/19] softfloat: use GCC builtins to count the leading zeros Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 02/19] cpu-all.h: define CPU_LDoubleU Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 03/19] target-i386: use CPU_LDoubleU instead of a private union Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 04/19] target-i386: use float unions from cpu-all.h Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 05/19] target-i386: add floatx_{add, mul, sub} and use them Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 06/19] softfloat: add float*_unordered_{, quiet}() functions Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 07/19] softfloat-native: add float*_unordered_quiet() functions Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 08/19] target-alpha: use new float64_unordered() function Aurelien Jarno
2011-04-13 14:52   ` Peter Maydell
2011-04-13 15:38     ` Richard Henderson
2011-04-13 15:42       ` Peter Maydell
2011-04-13 15:53         ` Richard Henderson
2011-04-13 18:18           ` Aurelien Jarno
2011-04-14  9:14       ` Peter Maydell
2011-04-14 15:14         ` Richard Henderson
2011-04-14 15:39           ` Peter Maydell
2011-04-14 16:27             ` Richard Henderson
2011-04-14 16:48               ` Peter Maydell
2011-04-14 17:01                 ` Richard Henderson
2011-04-12 21:59 ` [Qemu-devel] [PATCH 09/19] target-mips: use new float*_unordered*() functions Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 10/19] target-i386: fix CMPUNORDPS/D and CMPORDPS/D instructions Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 11/19] softfloat: rename float*_eq() into float*_eq_quiet() Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 12/19] softfloat: rename float*_eq_signaling() into float*_eq() Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 13/19] softfloat: move float*_eq and float*_eq_quiet Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 14/19] softfloat: improve description of comparison functions Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 15/19] target-arm: fix wrong usage of floatx80_eq_quiet() Aurelien Jarno
2011-04-12 22:41   ` Peter Maydell
2011-04-13 18:11     ` Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 16/19] target-alpha: fix wrong usage of float64_eq_quiet() Aurelien Jarno
2011-04-13 15:15   ` Peter Maydell
2011-04-12 21:59 ` [Qemu-devel] [PATCH 17/19] target-ppc: fix SPE comparison functions Aurelien Jarno
2011-04-13  2:40   ` Nathan Froyd
2011-04-13 18:11     ` Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 18/19] target-mips: simplify FP comparisons Aurelien Jarno
2011-04-12 21:59 ` [Qemu-devel] [PATCH 19/19] target-mips: don't hardcode softfloat exception bits Aurelien Jarno
2011-04-13 15:45 ` [Qemu-devel] [PATCH 00/19] softfloat and FPU fixes/improvements Peter Maydell

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).