All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat
@ 2011-04-18 20:59 Aurelien Jarno
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
                   ` (19 more replies)
  0 siblings, 20 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

The i386 target is the last one still using softfloat-native. Compared 
to softfloat, it is faster but lacks exception handling, float80 
(except on x86 hosts) and float128, as well as correctness (use NaN 
propagation from the host, different corner cases, etc.). It's API has
also diverged from softfloat, meaning it's not easily possible to select
softfloat or softfloat-native at build-time.

This patch series adjust softfloat, softfloat-native, and target-i386,
so that it's possible to build this target with either implementation.
It's only a transient state until softfloat-native is definitely 
removed. This also mean that some code changes in target-i386 are not
the best possible, as writing code that work on both is sometimes 
difficult. This will have to be fixed after the softfloat removal.

For the trigonometic and logarithmic functions, which are not (yet)
available in softfloat (neither in softfloat-native actually), I have
chosen to convert the floatx80 value to double and use the host 
function. This limits the precision to float64, but anyway the current
code was already using the double version of these functions (instead
of the long double version for floatx80 precision).

I have tested these patches by using the GNU libc testsuite, and 
comparing the results before and after. This patch series already 
globally improve the testsuite results, though on some trigonometric 
functions some tests are now failing and some tests are now passing,
due to precision issues. In any case, these precision issues are limited
to the last two bits of the 80-bit value, so it's safe to ignore this
issue for now.

I already have another patch series in preparation, which does the 
actual softfloat removal, clean the generic and target-i386 codes, add 
exception support, and add a softfloat log2() function. However it's
the following step, and I prefer first to get this patch series 
discussed and hopefully accepted before.


Aurelien Jarno (20):
  softfloat: fix floatx80 handling of NaN
  softfloat: fix floatx80_is_infinity()
  softfloat: add floatx80 constants
  softfloat: add pi constants
  softfloat-native: add a few constant values
  softfloat: add floatx80_compare*() functions
  softfloat: fix float*_scalnb() corner cases
  softfloat-native: fix float*_scalbn() functions
  softfloat-native: add float*_is_any_nan() functions
  target-i386: fix helper_fscale() wrt softfloat
  target-i386: fix helper_flbd_ST0() wrt softfloat
  target-i386: fix helper_fxtract() wrt softfloat
  target-i386: fix helper_fdiv() wrt softfloat
  target-i386: fix helper_fsqrt() wrt softfloat
  target-i386: replace approx_rsqrt and approx_rcp by softfloat ops
  target-i386: add CPU86_LDouble <-> double conversion functions
  target-i386: fix logarithmic and trigonometric helpers wrt softfloat
  target-i386: fix helper_fprem() and helper_fprem1() wrt softfloat
  target-i386: fix constants wrt softfloat
  target-i386: switch to softfloat

 configure                  |    3 -
 fpu/softfloat-native.c     |   26 ++++++
 fpu/softfloat-native.h     |   36 +++++++-
 fpu/softfloat-specialize.h |   19 +++--
 fpu/softfloat.c            |   93 +++++++++++++++++++-
 fpu/softfloat.h            |   14 +++-
 target-i386/exec.h         |   20 +++++
 target-i386/op_helper.c    |  205 ++++++++++++++++++++++++++-----------------
 target-i386/ops_sse.h      |   36 +++++---
 9 files changed, 341 insertions(+), 111 deletions(-)

-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 10:53   ` Peter Maydell
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

The floatx80 format uses an explicit bit that should be taken into account
when converting to and from commonNaN format.

When converting to commonNaN, the explicit bit should be removed if it is
a 1, and a default NaN should be used if it is 0.

When converting from commonNan, the explicit bit should be added.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-specialize.h |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b110187..fb2b5b4 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -603,9 +603,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
     commonNaNT z;
 
     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
-    z.sign = a.high>>15;
-    z.low = 0;
-    z.high = a.low;
+    if ( a.low >> 63 ) {
+        z.sign = a.high >> 15;
+        z.low = 0;
+        z.high = a.low << 1;
+    } else {
+        z.sign = floatx80_default_nan_high >> 15;
+        z.low = 0;
+        z.high = floatx80_default_nan_low << 1;
+    }
     return z;
 }
 
@@ -624,10 +630,11 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
         return z;
     }
 
-    if (a.high)
-        z.low = a.high;
-    else
+    if (a.high) {
+        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
+    } else {
         z.low = floatx80_default_nan_low;
+    }
     z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
     return z;
 }
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity()
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 10:55   ` Peter Maydell
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants Aurelien Jarno
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

With floatx80, the explicit bit is set for infinity.

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

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 340f0a9..3363128 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -566,7 +566,7 @@ INLINE floatx80 floatx80_chs(floatx80 a)
 
 INLINE int floatx80_is_infinity(floatx80 a)
 {
-    return (a.high & 0x7fff) == 0x7fff && a.low == 0;
+    return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
 }
 
 INLINE int floatx80_is_neg(floatx80 a)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 11:07   ` Peter Maydell
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 04/20] softfloat: add pi constants Aurelien Jarno
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add floatx80 constants similarly to float32 or float64.

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

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 3363128..90e0c41 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -154,6 +154,7 @@ typedef struct {
     uint64_t low;
     uint16_t high;
 } floatx80;
+#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
 #endif
 #ifdef FLOAT128
 typedef struct {
@@ -584,6 +585,12 @@ INLINE int floatx80_is_any_nan(floatx80 a)
     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
 }
 
+#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
+#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
+#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
+#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
+#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
+
 /*----------------------------------------------------------------------------
 | The pattern for a default generated extended double-precision NaN.  The
 | `high' and `low' values hold the most- and least-significant bits,
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 04/20] softfloat: add pi constants
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (2 preceding siblings ...)
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 11:10   ` Peter Maydell
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values Aurelien Jarno
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add a pi constant for float32, float64, floatx80. It will be used by
target-i386 and later by the trigonometric functions.

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

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 90e0c41..52f49da 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -387,6 +387,7 @@ INLINE float32 float32_set_sign(float32 a, int sign)
 #define float32_zero make_float32(0)
 #define float32_one make_float32(0x3f800000)
 #define float32_ln2 make_float32(0x3f317218)
+#define float32_pi make_float32(0x40490fdb)
 #define float32_half make_float32(0x3f000000)
 #define float32_infinity make_float32(0x7f800000)
 
@@ -499,6 +500,7 @@ INLINE float64 float64_set_sign(float64 a, int sign)
 #define float64_zero make_float64(0)
 #define float64_one make_float64(0x3ff0000000000000LL)
 #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
+#define float64_pi make_float32(0x400921fb54442d18LL)
 #define float64_half make_float64(0x3fe0000000000000LL)
 #define float64_infinity make_float64(0x7ff0000000000000LL)
 
@@ -588,6 +590,7 @@ INLINE int floatx80_is_any_nan(floatx80 a)
 #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
 #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
 #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
+#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
 #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
 #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
 
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (3 preceding siblings ...)
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 04/20] softfloat: add pi constants Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 11:12   ` Peter Maydell
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index ea7a15e..97fb3c7 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -172,6 +172,15 @@ float128 int64_to_float128( int64_t STATUS_PARAM);
 #endif
 
 /*----------------------------------------------------------------------------
+| Software IEC/IEEE single-precision conversion constants.
+*----------------------------------------------------------------------------*/
+#define float32_zero (0.0)
+#define float32_one (1.0)
+#define float32_ln2 (0.6931471)
+#define float32_pi (3.1415926)
+#define float32_half (0.5)
+
+/*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int float32_to_int32( float32  STATUS_PARAM);
@@ -280,6 +289,15 @@ INLINE float32 float32_scalbn(float32 a, int n)
 }
 
 /*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision conversion constants.
+*----------------------------------------------------------------------------*/
+#define float64_zero (0.0)
+#define float64_one (1.0)
+#define float64_ln2 (0.693147180559945)
+#define float64_pi (3.141592653589793)
+#define float64_half (0.5)
+
+/*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int float64_to_int32( float64 STATUS_PARAM );
@@ -394,6 +412,15 @@ INLINE float64 float64_scalbn(float64 a, int n)
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision conversion constants.
+*----------------------------------------------------------------------------*/
+#define floatx80_zero (0.0L)
+#define floatx80_one (1.0L)
+#define floatx80_ln2 (0.69314718055994530943L)
+#define floatx80_pi (3.14159265358979323851L)
+#define floatx80_half (0.5L)
+
+/*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int floatx80_to_int32( floatx80 STATUS_PARAM );
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (4 preceding siblings ...)
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 11:16   ` Peter Maydell
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases Aurelien Jarno
                   ` (13 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add floatx80_compare() and floatx80_compare_quiet() functions to match
the softfloat-native ones.

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

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6ce0b61..4368069 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6190,6 +6190,52 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM )  \
 COMPARE(32, 0xff)
 COMPARE(64, 0x7ff)
 
+INLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
+                                      int is_quiet STATUS_PARAM )
+{
+    flag aSign, bSign;
+
+    if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
+          ( extractFloatx80Frac( a )<<1 ) ) ||
+        ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
+          ( extractFloatx80Frac( b )<<1 ) )) {
+        if (!is_quiet ||
+            floatx80_is_signaling_nan( a ) ||
+            floatx80_is_signaling_nan( b ) ) {
+            float_raise( float_flag_invalid STATUS_VAR);
+        }
+        return float_relation_unordered;
+    }
+    aSign = extractFloatx80Sign( a );
+    bSign = extractFloatx80Sign( b );
+    if ( aSign != bSign ) {
+
+        if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
+             ( ( a.low | b.low ) == 0 ) ) {
+            /* zero case */
+            return float_relation_equal;
+        } else {
+            return 1 - (2 * aSign);
+        }
+    } else {
+        if (a.low == b.low && a.high == b.high) {
+            return float_relation_equal;
+        } else {
+            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
+        }
+    }
+}
+
+int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    return floatx80_compare_internal(a, b, 0 STATUS_VAR);
+}
+
+int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+    return floatx80_compare_internal(a, b, 1 STATUS_VAR);
+}
+
 INLINE int float128_compare_internal( float128 a, float128 b,
                                       int is_quiet STATUS_PARAM )
 {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 52f49da..2055922 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -550,6 +550,8 @@ 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 );
+int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_quiet_nan( floatx80 );
 int floatx80_is_signaling_nan( floatx80 );
 floatx80 floatx80_maybe_silence_nan( floatx80 );
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (5 preceding siblings ...)
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
@ 2011-04-18 20:59 ` Aurelien Jarno
  2011-04-19 11:57   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 20:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

float*_scalnb() were not taking into account all cases. This patch fixes
some corner cases:
- NaN values in input were not properly propagated and the invalid flag
  not correctly raised. Use propagateFloat*NaN() for that.
- NaN or infinite values in input of floatx80_scalnb() were not correctly
  detected due to a typo.
- The sum of exponent and n could overflow, leading to strange results.
  Additionally having int16 defined to int make that happening for a very
  small range of values. Fix that by saturating n to the maximum exponent
  range, and using an explicit wider type if needed.

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

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4368069..8f755c3 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6333,7 +6333,7 @@ MINMAX(64, 0x7ff)
 float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int16 aExp;
+    int16_t aExp;
     uint32_t aSig;
 
     a = float32_squash_input_denormal(a STATUS_VAR);
@@ -6342,6 +6342,9 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
     aSign = extractFloat32Sign( a );
 
     if ( aExp == 0xFF ) {
+        if ( aSig ) {
+            return propagateFloat32NaN( a, a STATUS_VAR );
+        }
         return a;
     }
     if ( aExp != 0 )
@@ -6349,6 +6352,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
     else if ( aSig == 0 )
         return a;
 
+    if (n > 0x80) {
+        n = 0x80;
+    } else if (n < -0x80) {
+        n = -0x80;
+    }
+
     aExp += n - 1;
     aSig <<= 7;
     return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
@@ -6357,7 +6366,7 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
 float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int16 aExp;
+    int16_t aExp;
     uint64_t aSig;
 
     a = float64_squash_input_denormal(a STATUS_VAR);
@@ -6366,6 +6375,9 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
     aSign = extractFloat64Sign( a );
 
     if ( aExp == 0x7FF ) {
+        if ( aSig ) {
+            return propagateFloat64NaN( a, a STATUS_VAR );
+        }
         return a;
     }
     if ( aExp != 0 )
@@ -6373,6 +6385,12 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
     else if ( aSig == 0 )
         return a;
 
+    if (n > 0x1000) {
+        n = 0x1000;
+    } else if (n < -0x1000) {
+        n = -0x1000;
+    }
+
     aExp += n - 1;
     aSig <<= 10;
     return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
@@ -6382,19 +6400,29 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int16 aExp;
+    int32_t aExp;
     uint64_t aSig;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
     aSign = extractFloatx80Sign( a );
 
-    if ( aExp == 0x7FF ) {
+    if ( aExp == 0x7FFF ) {
+        if ( aSig<<1 ) {
+            return propagateFloatx80NaN( a, a STATUS_VAR );
+        }
         return a;
     }
+
     if (aExp == 0 && aSig == 0)
         return a;
 
+    if (n > 0x10000) {
+        n = 0x10000;
+    } else if (n < -0x10000) {
+        n = -0x10000;
+    }
+
     aExp += n;
     return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
                                           aSign, aExp, aSig, 0 STATUS_VAR );
@@ -6405,7 +6433,7 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
 float128 float128_scalbn( float128 a, int n STATUS_PARAM )
 {
     flag aSign;
-    int32 aExp;
+    int32_t aExp;
     uint64_t aSig0, aSig1;
 
     aSig1 = extractFloat128Frac1( a );
@@ -6413,6 +6441,9 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
     aExp = extractFloat128Exp( a );
     aSign = extractFloat128Sign( a );
     if ( aExp == 0x7FFF ) {
+        if ( aSig0 | aSig1 ) {
+            return propagateFloat128NaN( a, a STATUS_VAR );
+        }
         return a;
     }
     if ( aExp != 0 )
@@ -6420,6 +6451,12 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
     else if ( aSig0 == 0 && aSig1 == 0 )
         return a;
 
+    if (n > 0x10000) {
+        n = 0x10000;
+    } else if (n < -0x10000) {
+        n = -0x10000;
+    }
+
     aExp += n - 1;
     return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
                                           STATUS_VAR );
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (6 preceding siblings ...)
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 12:35   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

float*_scalbn() should be able to take a status parameter. Fix that.

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

diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index 97fb3c7..f497e64 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -283,7 +283,7 @@ INLINE float32 float32_is_zero(float32 a)
     return fpclassify(a) == FP_ZERO;
 }
 
-INLINE float32 float32_scalbn(float32 a, int n)
+INLINE float32 float32_scalbn(float32 a, int n STATUS_PARAM)
 {
     return scalbnf(a, n);
 }
@@ -404,7 +404,7 @@ INLINE float64 float64_is_zero(float64 a)
     return fpclassify(a) == FP_ZERO;
 }
 
-INLINE float64 float64_scalbn(float64 a, int n)
+INLINE float64 float64_scalbn(float64 a, int n STATUS_PARAM)
 {
     return scalbn(a, n);
 }
@@ -520,7 +520,7 @@ INLINE floatx80 floatx80_is_zero(floatx80 a)
     return fpclassify(a) == FP_ZERO;
 }
 
-INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
+INLINE floatx80 floatx80_scalbn(floatx80 a, int n STATUS_PARAM)
 {
     return scalbnl(a, n);
 }
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (7 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 12:42   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add float*_is_any_nan() functions to match the softfloat API.

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

diff --git a/fpu/softfloat-native.c b/fpu/softfloat-native.c
index 50355a4..8848651 100644
--- a/fpu/softfloat-native.c
+++ b/fpu/softfloat-native.c
@@ -263,6 +263,15 @@ int float32_is_quiet_nan( float32 a1 )
     return ( 0xFF800000 < ( a<<1 ) );
 }
 
+int float32_is_any_nan( float32 a1 )
+{
+    float32u u;
+    uint32_t a;
+    u.f = a1;
+    a = u.i;
+    return (a & ~(1 << 31)) > 0x7f800000U;
+}
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
@@ -422,6 +431,16 @@ int float64_is_quiet_nan( float64 a1 )
 
 }
 
+int float64_is_any_nan( float64 a1 )
+{
+    float64u u;
+    uint64_t a;
+    u.f = a1;
+    a = u.i;
+
+    return (a & ~(1ULL << 63)) > LIT64 (0x7FF0000000000000 );
+}
+
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
@@ -511,4 +530,11 @@ int floatx80_is_quiet_nan( floatx80 a1 )
     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( u.i.low<<1 );
 }
 
+int floatx80_is_any_nan( floatx80 a1 )
+{
+    floatx80u u;
+    u.f = a1;
+    return ((u.i.high & 0x7FFF) == 0x7FFF) && ( u.i.low<<1 );
+}
+
 #endif
diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
index f497e64..6afb74a 100644
--- a/fpu/softfloat-native.h
+++ b/fpu/softfloat-native.h
@@ -255,6 +255,7 @@ int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 int float32_is_signaling_nan( float32 );
 int float32_is_quiet_nan( float32 );
+int float32_is_any_nan( float32 );
 
 INLINE float32 float32_abs(float32 a)
 {
@@ -375,6 +376,7 @@ INLINE int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM)
 int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 int float64_is_signaling_nan( float64 );
+int float64_is_any_nan( float64 );
 int float64_is_quiet_nan( float64 );
 
 INLINE float64 float64_abs(float64 a)
@@ -492,6 +494,7 @@ int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
 int floatx80_is_signaling_nan( floatx80 );
 int floatx80_is_quiet_nan( floatx80 );
+int floatx80_is_any_nan( floatx80 );
 
 INLINE floatx80 floatx80_abs(floatx80 a)
 {
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (8 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 16:57   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() " Aurelien Jarno
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Use the scalbn softfloat function to implement helper_fscale(). This
fixes corner cases (e.g. NaN) and makes a few more GNU libc math tests
to pass.

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

diff --git a/target-i386/exec.h b/target-i386/exec.h
index ae6b947..211cc8c 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -115,9 +115,11 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
+#define floatx_scalbn floatx80_scalbn
 #define floatx_round_to_int floatx80_round_to_int
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
+#define floatx_is_any_nan floatx80_is_any_nan
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -134,9 +136,11 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
+#define floatx_scalbn float64_scalbn
 #define floatx_round_to_int float64_round_to_int
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
+#define floatx_is_any_nan float64_is_any_nan
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index a73427f..f614893 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4174,7 +4174,12 @@ void helper_frndint(void)
 
 void helper_fscale(void)
 {
-    ST0 = ldexp (ST0, (int)(ST1));
+    if (floatx_is_any_nan(ST1)) {
+        ST0 = ST1;
+    } else {
+        int n = floatx_to_int32_round_to_zero(ST1, &env->fp_status);
+        ST0 = floatx_scalbn(ST0, n, &env->fp_status);
+    }
 }
 
 void helper_fsin(void)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (9 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:06   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f614893..7dddd37 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3920,9 +3920,10 @@ void helper_fbld_ST0(target_ulong ptr)
         v = ldub(ptr + i);
         val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
     }
-    tmp = val;
-    if (ldub(ptr + 9) & 0x80)
-        tmp = -tmp;
+    if (ldub(ptr + 9) & 0x80) {
+        val = -val;
+    }
+    tmp = int64_to_floatx(val, &env->fp_status);
     fpush();
     ST0 = tmp;
 }
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (10 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() " Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:46   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

With softfloat it's not possible to play with the overflow of an
unsigned value to get the 0 case partially correct. Use a special case
for that. Using a division to generate an infinity is the easiest way
that works for both softfloat and softfloat-native.

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

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 7dddd37..9e5ca72 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4005,15 +4005,24 @@ void helper_fpatan(void)
 void helper_fxtract(void)
 {
     CPU86_LDoubleU temp;
-    unsigned int expdif;
 
     temp.d = ST0;
-    expdif = EXPD(temp) - EXPBIAS;
-    /*DP exponent bias*/
-    ST0 = expdif;
-    fpush();
-    BIASEXPONENT(temp);
-    ST0 = temp.d;
+
+    if (floatx_is_zero(ST0)) {
+        /* Easy way to generate -inf and raising division by 0 exception */
+        ST0 = floatx_div(floatx_chs(floatx_one), floatx_zero, &env->fp_status);
+        fpush();
+        ST0 = temp.d;
+    } else {
+        int expdif;
+
+        expdif = EXPD(temp) - EXPBIAS;
+        /*DP exponent bias*/
+        ST0 = int32_to_floatx(expdif, &env->fp_status);
+        fpush();
+        BIASEXPONENT(temp);
+        ST0 = temp.d;
+    }
 }
 
 void helper_fprem1(void)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (11 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:11   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 211cc8c..b2af894 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -111,6 +111,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_to_float32 floatx80_to_float32
 #define floatx_to_float64 floatx80_to_float64
 #define floatx_add floatx80_add
+#define floatx_div floatx80_div
 #define floatx_mul floatx80_mul
 #define floatx_sub floatx80_sub
 #define floatx_abs floatx80_abs
@@ -120,6 +121,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
 #define floatx_is_any_nan floatx80_is_any_nan
+#define floatx_is_zero floatx80_is_zero
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -132,6 +134,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_to_float32 float64_to_float32
 #define floatx_to_float64(x, e) (x)
 #define floatx_add float64_add
+#define floatx_div float64_div
 #define floatx_mul float64_mul
 #define floatx_sub float64_sub
 #define floatx_abs float64_abs
@@ -141,6 +144,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
 #define floatx_is_any_nan float64_is_any_nan
+#define floatx_is_zero float64_is_zero
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 9e5ca72..d0d639c 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3440,9 +3440,10 @@ static void fpu_set_exception(int mask)
 
 static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
 {
-    if (b == 0.0)
+    if (floatx_is_zero(b)) {
         fpu_set_exception(FPUS_ZE);
-    return a / b;
+    }
+    return floatx_div(a, b, &env->fp_status);
 }
 
 static void fpu_raise_exception(void)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (12 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:13   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
                   ` (5 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

diff --git a/target-i386/exec.h b/target-i386/exec.h
index b2af894..292e0de 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -114,6 +114,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_div floatx80_div
 #define floatx_mul floatx80_mul
 #define floatx_sub floatx80_sub
+#define floatx_sqrt floatx80_sqrt
 #define floatx_abs floatx80_abs
 #define floatx_chs floatx80_chs
 #define floatx_scalbn floatx80_scalbn
@@ -121,6 +122,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare floatx80_compare
 #define floatx_compare_quiet floatx80_compare_quiet
 #define floatx_is_any_nan floatx80_is_any_nan
+#define floatx_is_neg floatx80_is_neg
 #define floatx_is_zero floatx80_is_zero
 #else
 #define floatx_to_int32 float64_to_int32
@@ -137,6 +139,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_div float64_div
 #define floatx_mul float64_mul
 #define floatx_sub float64_sub
+#define floatx_sqrt float64_sqrt
 #define floatx_abs float64_abs
 #define floatx_chs float64_chs
 #define floatx_scalbn float64_scalbn
@@ -144,6 +147,7 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_compare float64_compare
 #define floatx_compare_quiet float64_compare_quiet
 #define floatx_is_any_nan float64_is_any_nan
+#define floatx_is_neg float64_is_neg
 #define floatx_is_zero float64_is_zero
 #endif
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index d0d639c..d935488 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4152,14 +4152,11 @@ void helper_fyl2xp1(void)
 
 void helper_fsqrt(void)
 {
-    CPU86_LDouble fptemp;
-
-    fptemp = ST0;
-    if (fptemp<0.0) {
+    if (floatx_is_neg(ST0)) {
         env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
         env->fpus |= 0x400;
     }
-    ST0 = sqrt(fptemp);
+    ST0 = floatx_sqrt(ST0, &env->fp_status);
 }
 
 void helper_fsincos(void)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (13 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:20   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-i386/op_helper.c |   10 ----------
 target-i386/ops_sse.h   |   36 ++++++++++++++++++++++++------------
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index d935488..9628d27 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4794,16 +4794,6 @@ void helper_boundl(target_ulong a0, int v)
     }
 }
 
-static float approx_rsqrt(float a)
-{
-    return 1.0 / sqrt(a);
-}
-
-static float approx_rcp(float a)
-{
-    return 1.0 / a;
-}
-
 #if !defined(CONFIG_USER_ONLY)
 
 #define MMUSUFFIX _mmu
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index ac0f150..703be99 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -778,28 +778,38 @@ int64_t helper_cvttsd2sq(XMMReg *s)
 
 void helper_rsqrtps(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
-    d->XMM_S(1) = approx_rsqrt(s->XMM_S(1));
-    d->XMM_S(2) = approx_rsqrt(s->XMM_S(2));
-    d->XMM_S(3) = approx_rsqrt(s->XMM_S(3));
+    d->XMM_S(0) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(0), &env->sse_status),
+                              &env->sse_status);
+    d->XMM_S(1) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(1), &env->sse_status),
+                              &env->sse_status);
+    d->XMM_S(2) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(2), &env->sse_status),
+                              &env->sse_status);
+    d->XMM_S(3) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(3), &env->sse_status),
+                              &env->sse_status);
 }
 
 void helper_rsqrtss(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
+    d->XMM_S(0) = float32_div(float32_one,
+                              float32_sqrt(s->XMM_S(0), &env->sse_status),
+                              &env->sse_status);
 }
 
 void helper_rcpps(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rcp(s->XMM_S(0));
-    d->XMM_S(1) = approx_rcp(s->XMM_S(1));
-    d->XMM_S(2) = approx_rcp(s->XMM_S(2));
-    d->XMM_S(3) = approx_rcp(s->XMM_S(3));
+    d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
+    d->XMM_S(1) = float32_div(float32_one, s->XMM_S(1), &env->sse_status);
+    d->XMM_S(2) = float32_div(float32_one, s->XMM_S(2), &env->sse_status);
+    d->XMM_S(3) = float32_div(float32_one, s->XMM_S(3), &env->sse_status);
 }
 
 void helper_rcpss(XMMReg *d, XMMReg *s)
 {
-    d->XMM_S(0) = approx_rcp(s->XMM_S(0));
+    d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status);
 }
 
 static inline uint64_t helper_extrq(uint64_t src, int shift, int len)
@@ -1272,14 +1282,16 @@ void helper_pfpnacc(MMXReg *d, MMXReg *s)
 
 void helper_pfrcp(MMXReg *d, MMXReg *s)
 {
-    d->MMX_S(0) = approx_rcp(s->MMX_S(0));
+    d->MMX_S(0) = float32_div(float32_one, s->MMX_S(0), &env->mmx_status);
     d->MMX_S(1) = d->MMX_S(0);
 }
 
 void helper_pfrsqrt(MMXReg *d, MMXReg *s)
 {
     d->MMX_L(1) = s->MMX_L(0) & 0x7fffffff;
-    d->MMX_S(1) = approx_rsqrt(d->MMX_S(1));
+    d->MMX_S(1) = float32_div(float32_one,
+                              float32_sqrt(d->MMX_S(1), &env->mmx_status),
+                              &env->mmx_status);
     d->MMX_L(1) |= s->MMX_L(0) & 0x80000000;
     d->MMX_L(0) = d->MMX_L(1);
 }
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (14 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:31   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add functions to convert CPU86_LDouble to double and vice versa. They
are going to be used to implement logarithmic and trigonometric function
until softfloat implement them.

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

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 9628d27..f69458d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -3431,6 +3431,28 @@ void helper_verw(target_ulong selector1)
 
 /* x87 FPU helpers */
 
+static inline double CPU86_LDouble_to_double(CPU86_LDouble a)
+{
+    union {
+        float64 f64;
+        double d;
+    } u;
+
+    u.f64 = floatx_to_float64(a, &env->fp_status);
+    return u.d;
+}
+
+static inline CPU86_LDouble double_to_CPU86_LDouble(double a)
+{
+    union {
+        float64 f64;
+        double d;
+    } u;
+
+    u.d = a;
+    return float64_to_floatx(u.f64, &env->fp_status);
+}
+
 static void fpu_set_exception(int mask)
 {
     env->fpus |= mask;
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (15 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:37   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Use the new CPU86_LDouble <-> double conversion functions to make logarithmic
and trigonometric helpers working with softfloat.

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

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f69458d..4671a96 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -17,6 +17,7 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <math.h>
 #include "exec.h"
 #include "exec-all.h"
 #include "host-utils.h"
@@ -3981,17 +3982,19 @@ void helper_fbst_ST0(target_ulong ptr)
 
 void helper_f2xm1(void)
 {
-    ST0 = pow(2.0,ST0) - 1.0;
+    double val = CPU86_LDouble_to_double(ST0);
+    val = pow(2.0, val) - 1.0;
+    ST0 = double_to_CPU86_LDouble(val);
 }
 
 void helper_fyl2x(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if (fptemp>0.0){
-        fptemp = log(fptemp)/log(2.0);	 /* log2(ST) */
-        ST1 *= fptemp;
+        fptemp = log(fptemp)/log(2.0);    /* log2(ST) */
+        fptemp *= CPU86_LDouble_to_double(ST1);
+        ST1 = double_to_CPU86_LDouble(fptemp);
         fpop();
     } else {
         env->fpus &= (~0x4700);
@@ -4001,15 +4004,15 @@ void helper_fyl2x(void)
 
 void helper_fptan(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = tan(fptemp);
+        fptemp = tan(fptemp);
+        ST0 = double_to_CPU86_LDouble(fptemp);
         fpush();
-        ST0 = 1.0;
+        ST0 = double_to_CPU86_LDouble(1.0);
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg| < 2**52 only */
     }
@@ -4017,11 +4020,11 @@ void helper_fptan(void)
 
 void helper_fpatan(void)
 {
-    CPU86_LDouble fptemp, fpsrcop;
+    double fptemp, fpsrcop;
 
-    fpsrcop = ST1;
-    fptemp = ST0;
-    ST1 = atan2(fpsrcop,fptemp);
+    fpsrcop = CPU86_LDouble_to_double(ST1);
+    fptemp = CPU86_LDouble_to_double(ST0);
+    ST1 = double_to_CPU86_LDouble(atan2(fpsrcop, fptemp));
     fpop();
 }
 
@@ -4159,12 +4162,12 @@ void helper_fprem(void)
 
 void helper_fyl2xp1(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if ((fptemp+1.0)>0.0) {
         fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
-        ST1 *= fptemp;
+        fptemp *= CPU86_LDouble_to_double(ST1);
+        ST1 = double_to_CPU86_LDouble(fptemp);
         fpop();
     } else {
         env->fpus &= (~0x4700);
@@ -4183,15 +4186,14 @@ void helper_fsqrt(void)
 
 void helper_fsincos(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = sin(fptemp);
+        ST0 = double_to_CPU86_LDouble(sin(fptemp));
         fpush();
-        ST0 = cos(fptemp);
+        ST0 = double_to_CPU86_LDouble(cos(fptemp));
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg| < 2**63 only */
     }
@@ -4214,13 +4216,12 @@ void helper_fscale(void)
 
 void helper_fsin(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = sin(fptemp);
+        ST0 = double_to_CPU86_LDouble(sin(fptemp));
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg| < 2**53 only */
     }
@@ -4228,13 +4229,12 @@ void helper_fsin(void)
 
 void helper_fcos(void)
 {
-    CPU86_LDouble fptemp;
+    double fptemp = CPU86_LDouble_to_double(ST0);
 
-    fptemp = ST0;
     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
         env->fpus |= 0x400;
     } else {
-        ST0 = cos(fptemp);
+        ST0 = double_to_CPU86_LDouble(cos(fptemp));
         env->fpus &= (~0x400);  /* C2 <-- 0 */
         /* the above code is for  |arg5 < 2**63 only */
     }
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (16 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:41   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 19/20] target-i386: fix constants " Aurelien Jarno
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat Aurelien Jarno
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 4671a96..0c4f0da 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -4053,21 +4053,24 @@ void helper_fxtract(void)
 
 void helper_fprem1(void)
 {
-    CPU86_LDouble dblq, fpsrcop, fptemp;
+    double st0, st1, dblq, fpsrcop, fptemp;
     CPU86_LDoubleU fpsrcop1, fptemp1;
     int expdif;
     signed long long int q;
 
-    if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
-        ST0 = 0.0 / 0.0; /* NaN */
+    st0 = CPU86_LDouble_to_double(ST0);
+    st1 = CPU86_LDouble_to_double(ST1);
+
+    if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
+        ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
         return;
     }
 
-    fpsrcop = ST0;
-    fptemp = ST1;
-    fpsrcop1.d = fpsrcop;
-    fptemp1.d = fptemp;
+    fpsrcop = st0;
+    fptemp = st1;
+    fpsrcop1.d = ST0;
+    fptemp1.d = ST1;
     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
 
     if (expdif < 0) {
@@ -4081,7 +4084,7 @@ void helper_fprem1(void)
         dblq = fpsrcop / fptemp;
         /* round dblq towards nearest integer */
         dblq = rint(dblq);
-        ST0 = fpsrcop - fptemp * dblq;
+        st0 = fpsrcop - fptemp * dblq;
 
         /* convert dblq to q by truncating towards zero */
         if (dblq < 0.0)
@@ -4097,31 +4100,35 @@ void helper_fprem1(void)
     } else {
         env->fpus |= 0x400;  /* C2 <-- 1 */
         fptemp = pow(2.0, expdif - 50);
-        fpsrcop = (ST0 / ST1) / fptemp;
+        fpsrcop = (st0 / st1) / fptemp;
         /* fpsrcop = integer obtained by chopping */
         fpsrcop = (fpsrcop < 0.0) ?
                   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
-        ST0 -= (ST1 * fpsrcop * fptemp);
+        st0 -= (st1 * fpsrcop * fptemp);
     }
+    ST0 = double_to_CPU86_LDouble(st0);
 }
 
 void helper_fprem(void)
 {
-    CPU86_LDouble dblq, fpsrcop, fptemp;
+    double st0, st1, dblq, fpsrcop, fptemp;
     CPU86_LDoubleU fpsrcop1, fptemp1;
     int expdif;
     signed long long int q;
 
-    if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) {
-       ST0 = 0.0 / 0.0; /* NaN */
+    st0 = CPU86_LDouble_to_double(ST0);
+    st1 = CPU86_LDouble_to_double(ST1);
+
+    if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
+       ST0 = double_to_CPU86_LDouble(0.0 / 0.0); /* NaN */
        env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
        return;
     }
 
-    fpsrcop = (CPU86_LDouble)ST0;
-    fptemp = (CPU86_LDouble)ST1;
-    fpsrcop1.d = fpsrcop;
-    fptemp1.d = fptemp;
+    fpsrcop = st0;
+    fptemp = st1;
+    fpsrcop1.d = ST0;
+    fptemp1.d = ST1;
     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
 
     if (expdif < 0) {
@@ -4135,7 +4142,7 @@ void helper_fprem(void)
         dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/;
         /* round dblq towards zero */
         dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq);
-        ST0 = fpsrcop/*ST0*/ - fptemp * dblq;
+        st0 = fpsrcop/*ST0*/ - fptemp * dblq;
 
         /* convert dblq to q by truncating towards zero */
         if (dblq < 0.0)
@@ -4152,12 +4159,13 @@ void helper_fprem(void)
         int N = 32 + (expdif % 32); /* as per AMD docs */
         env->fpus |= 0x400;  /* C2 <-- 1 */
         fptemp = pow(2.0, (double)(expdif - N));
-        fpsrcop = (ST0 / ST1) / fptemp;
+        fpsrcop = (st0 / st1) / fptemp;
         /* fpsrcop = integer obtained by chopping */
         fpsrcop = (fpsrcop < 0.0) ?
                   -(floor(fabs(fpsrcop))) : floor(fpsrcop);
-        ST0 -= (ST1 * fpsrcop * fptemp);
+        st0 -= (st1 * fpsrcop * fptemp);
     }
+    ST0 = double_to_CPU86_LDouble(st0);
 }
 
 void helper_fyl2xp1(void)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 19/20] target-i386: fix constants wrt softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (17 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:26   ` Peter Maydell
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat Aurelien Jarno
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

diff --git a/target-i386/exec.h b/target-i386/exec.h
index 292e0de..ee36a71 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -124,6 +124,10 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_is_any_nan floatx80_is_any_nan
 #define floatx_is_neg floatx80_is_neg
 #define floatx_is_zero floatx80_is_zero
+#define floatx_zero floatx80_zero
+#define floatx_one floatx80_one
+#define floatx_ln2 floatx80_ln2
+#define floatx_pi floatx80_pi
 #else
 #define floatx_to_int32 float64_to_int32
 #define floatx_to_int64 float64_to_int64
@@ -149,6 +153,10 @@ static inline void svm_check_intercept(uint32_t type)
 #define floatx_is_any_nan float64_is_any_nan
 #define floatx_is_neg float64_is_neg
 #define floatx_is_zero float64_is_zero
+#define floatx_zero float64_zero
+#define floatx_one float64_one
+#define floatx_ln2 float64_ln2
+#define floatx_pi float64_pi
 #endif
 
 #define RC_MASK         0xc00
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 0c4f0da..a9bb80d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -95,15 +95,25 @@ static const uint8_t rclb_table[32] = {
     6, 7, 8, 0, 1, 2, 3, 4,
 };
 
+#if defined(CONFIG_SOFTFLOAT)
+# define floatx_lg2 make_floatx80( 0x3ffd, 0x9a209a84fbcff799LL )
+# define floatx_l2e make_floatx80( 0x3fff, 0xb8aa3b295c17f0bcLL )
+# define floatx_l2t make_floatx80( 0x4000, 0xd49a784bcd1b8afeLL )
+#else
+# define floatx_lg2 (0.30102999566398119523L)
+# define floatx_l2e (1.44269504088896340739L)
+# define floatx_l2t (3.32192809488736234781L)
+#endif
+
 static const CPU86_LDouble f15rk[7] =
 {
-    0.00000000000000000000L,
-    1.00000000000000000000L,
-    3.14159265358979323851L,  /*pi*/
-    0.30102999566398119523L,  /*lg2*/
-    0.69314718055994530943L,  /*ln2*/
-    1.44269504088896340739L,  /*l2e*/
-    3.32192809488736234781L,  /*l2t*/
+    floatx_zero,
+    floatx_one,
+    floatx_pi,
+    floatx_lg2,
+    floatx_ln2,
+    floatx_l2e,
+    floatx_l2t,
 };
 
 /* broken thread support */
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat
  2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
                   ` (18 preceding siblings ...)
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 19/20] target-i386: fix constants " Aurelien Jarno
@ 2011-04-18 21:00 ` Aurelien Jarno
  2011-04-19 17:28   ` Peter Maydell
  19 siblings, 1 reply; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-18 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

This increase the correctness (precision, NaN values, corner cases) on
non-x86 machines, and add the possibility to handle the exception
correctly.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 configure |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index da2da04..6e445b4 100755
--- a/configure
+++ b/configure
@@ -3276,9 +3276,6 @@ if test ! -z "$gdb_xml_files" ; then
 fi
 
 case "$target_arch2" in
-  i386|x86_64)
-    echo "CONFIG_NOSOFTFLOAT=y" >> $config_target_mak
-    ;;
   *)
     echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
     ;;
-- 
1.7.2.3

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

* Re: [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
@ 2011-04-19 10:53   ` Peter Maydell
  2011-04-20  9:02     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 10:53 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> The floatx80 format uses an explicit bit that should be taken into account
> when converting to and from commonNaN format.
>
> When converting to commonNaN, the explicit bit should be removed if it is
> a 1, and a default NaN should be used if it is 0.
>
> When converting from commonNan, the explicit bit should be added.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  fpu/softfloat-specialize.h |   19 +++++++++++++------
>  1 files changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
> index b110187..fb2b5b4 100644
> --- a/fpu/softfloat-specialize.h
> +++ b/fpu/softfloat-specialize.h
> @@ -603,9 +603,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
>     commonNaNT z;
>
>     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
> -    z.sign = a.high>>15;
> -    z.low = 0;
> -    z.high = a.low;
> +    if ( a.low >> 63 ) {
> +        z.sign = a.high >> 15;
> +        z.low = 0;
> +        z.high = a.low << 1;
> +    } else {
> +        z.sign = floatx80_default_nan_high >> 15;
> +        z.low = 0;
> +        z.high = floatx80_default_nan_low << 1;
> +    }
>     return z;
>  }

The intel manuals don't seem to define what a number with non-zero exponent
field but explicit bit clear actually means. Presumably this (generate a
default NaN) is what the hardware does if you try to convert such a thing
to float64?

> @@ -624,10 +630,11 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
>         return z;
>     }
>
> -    if (a.high)
> -        z.low = a.high;
> -    else
> +    if (a.high) {
> +        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
> +    } else {
>         z.low = floatx80_default_nan_low;
> +    }
>     z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
>     return z;
>  }

I think the condition here should be "if (a.high >> 1)" -- otherwise we
might construct an infinity instead (explicit bit 1 but all fraction bits 0).
Also we are keeping the sign of the input even if we return the default
NaN. It might be better to start with
 uint64_t mantissa = a.high >> 1;
and then roll the 'mantissa == 0' check into the default_nan_mode if().

-- PMM

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

* Re: [Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity()
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
@ 2011-04-19 10:55   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 10:55 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> With floatx80, the explicit bit is set for infinity.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants Aurelien Jarno
@ 2011-04-19 11:07   ` Peter Maydell
  2011-04-20  9:05     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 11:07 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Add floatx80 constants similarly to float32 or float64.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

NB: I didn't actually check you got the ln2 value right :-)
Also for x86 these constants are stored internally with a 66 bit
mantissa and then rounded according to the current rounding mode,
so strictly speaking using these values isn't always the right
thing, but I think that's being overly picky for now.

-- PMM

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

* Re: [Qemu-devel] [PATCH 04/20] softfloat: add pi constants
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 04/20] softfloat: add pi constants Aurelien Jarno
@ 2011-04-19 11:10   ` Peter Maydell
  2011-04-20  9:05     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 11:10 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> +#define float64_pi make_float32(0x400921fb54442d18LL)

This doesn't look quite right :-)

-- PMM

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

* Re: [Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values Aurelien Jarno
@ 2011-04-19 11:12   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 11:12 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

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

* Re: [Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
@ 2011-04-19 11:16   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 11:16 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Add floatx80_compare() and floatx80_compare_quiet() functions to match
> the softfloat-native ones.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

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

* Re: [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases
  2011-04-18 20:59 ` [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases Aurelien Jarno
@ 2011-04-19 11:57   ` Peter Maydell
  2011-04-20  9:21     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 11:57 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:

> @@ -6349,6 +6352,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
>     else if ( aSig == 0 )
>         return a;
>
> +    if (n > 0x80) {
> +        n = 0x80;
> +    } else if (n < -0x80) {
> +        n = -0x80;
> +    }
> +
>     aExp += n - 1;
>     aSig <<= 7;
>     return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );

I don't think your if() condition is right here. Consider the
float32 00800000 (1.0 * 2 ^ -126 ; the smallest possible normalised
number); you can multiply this by, say, 2^253, without overflowing
to infinity. However your if() here means we'll incorrectly
compute the result of multiplying by 2^128 instead. s/0x80/0x200/
should work.

The others look OK to me. I would personally prefer to retain the int16
etc rather than moving to int16_t, but I don't quite feel strongly enough
to argue about it.

-- PMM

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

* Re: [Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
@ 2011-04-19 12:35   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 12:35 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> float*_scalbn() should be able to take a status parameter. Fix that.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
@ 2011-04-19 12:42   ` Peter Maydell
  2011-04-20  9:22     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 12:42 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:

> @@ -511,4 +530,11 @@ int floatx80_is_quiet_nan( floatx80 a1 )
>     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( u.i.low<<1 );
>  }
>
> +int floatx80_is_any_nan( floatx80 a1 )
> +{
> +    floatx80u u;
> +    u.f = a1;
> +    return ((u.i.high & 0x7FFF) == 0x7FFF) && ( u.i.low<<1 );
> +}
> +
>  #endif

As you can just see from the context, the new function is
actually identical to the existing floatx80_is_quiet_nan(),
but the latter is wrong, not this patch :-)

Nobody seems to use floatx80_is_quiet_nan() so if we're just
going to nuke softfloat-native shortly there's no point fixing
it I guess.

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
@ 2011-04-19 16:57   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 16:57 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Use the scalbn softfloat function to implement helper_fscale(). This
> fixes corner cases (e.g. NaN) and makes a few more GNU libc math tests
> to pass.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() " Aurelien Jarno
@ 2011-04-19 17:06   ` Peter Maydell
  2011-04-20  9:37     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:06 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-i386/op_helper.c |    7 ++++---
>  1 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
> index f614893..7dddd37 100644
> --- a/target-i386/op_helper.c
> +++ b/target-i386/op_helper.c
> @@ -3920,9 +3920,10 @@ void helper_fbld_ST0(target_ulong ptr)
>         v = ldub(ptr + i);
>         val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
>     }
> -    tmp = val;
> -    if (ldub(ptr + 9) & 0x80)
> -        tmp = -tmp;
> +    if (ldub(ptr + 9) & 0x80) {
> +        val = -val;
> +    }
> +    tmp = int64_to_floatx(val, &env->fp_status);
>     fpush();
>     ST0 = tmp;
>  }

This doesn't do the right thing for -0 (should generate -0,
not +0). I think:

 tmp = int64_to_floatx(val, &env->fp_status);
 if (ldub(ptr + 9) & 0x80) {
     floatx_chs(tmp);
 }

ought to do the right thing and work for both softfloat and
sf-native, but I haven't tested it.

-- PMM

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

* Re: [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
@ 2011-04-19 17:11   ` Peter Maydell
  2011-04-20  9:37     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:11 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> +++ b/target-i386/op_helper.c
> @@ -3440,9 +3440,10 @@ static void fpu_set_exception(int mask)
>
>  static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
>  {
> -    if (b == 0.0)
> +    if (floatx_is_zero(b)) {
>         fpu_set_exception(FPUS_ZE);
> -    return a / b;
> +    }
> +    return floatx_div(a, b, &env->fp_status);
>  }

When we get rid of softfloat-native we should be able to just
use softfloat's flag-raising code and get rid of this special
case of zero, right?

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
@ 2011-04-19 17:13   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:13 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
@ 2011-04-19 17:20   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:20 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 19/20] target-i386: fix constants wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 19/20] target-i386: fix constants " Aurelien Jarno
@ 2011-04-19 17:26   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:26 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat Aurelien Jarno
@ 2011-04-19 17:28   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:28 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> diff --git a/configure b/configure
> index da2da04..6e445b4 100755
> --- a/configure
> +++ b/configure
> @@ -3276,9 +3276,6 @@ if test ! -z "$gdb_xml_files" ; then
>  fi
>
>  case "$target_arch2" in
> -  i386|x86_64)
> -    echo "CONFIG_NOSOFTFLOAT=y" >> $config_target_mak
> -    ;;
>   *)
>     echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
>     ;;

Since the only case in this case statement is now "*", I think
it would make more sense to just delete it and have:
 echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
unconditionally.

-- PMM

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

* Re: [Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
@ 2011-04-19 17:31   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:31 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Add functions to convert CPU86_LDouble to double and vice versa. They
> are going to be used to implement logarithmic and trigonometric function
> until softfloat implement them.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
@ 2011-04-19 17:37   ` Peter Maydell
  2011-04-20  9:41     ` Aurelien Jarno
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:37 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> +#include <math.h>

Why does this patch need this? I couldn't see anywhere where
the patch added calls to math functions we weren't calling before,
or did I miss one?

>  void helper_fptan(void)
>  {
> -    CPU86_LDouble fptemp;
> +    double fptemp = CPU86_LDouble_to_double(ST0);
>
> -    fptemp = ST0;
>     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
>         env->fpus |= 0x400;
>     } else {
> -        ST0 = tan(fptemp);
> +        fptemp = tan(fptemp);
> +        ST0 = double_to_CPU86_LDouble(fptemp);
>         fpush();
> -        ST0 = 1.0;
> +        ST0 = double_to_CPU86_LDouble(1.0);

You could just say:
   ST0 = floatx_one;

-- PMM

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

* Re: [Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
@ 2011-04-19 17:41   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:41 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() wrt softfloat
  2011-04-18 21:00 ` [Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
@ 2011-04-19 17:46   ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-04-19 17:46 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> With softfloat it's not possible to play with the overflow of an
> unsigned value to get the 0 case partially correct. Use a special case
> for that. Using a division to generate an infinity is the easiest way
> that works for both softfloat and softfloat-native.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

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

* Re: [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-19 10:53   ` Peter Maydell
@ 2011-04-20  9:02     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:02 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 11:53:50AM +0100, Peter Maydell wrote:
> On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > The floatx80 format uses an explicit bit that should be taken into account
> > when converting to and from commonNaN format.
> >
> > When converting to commonNaN, the explicit bit should be removed if it is
> > a 1, and a default NaN should be used if it is 0.
> >
> > When converting from commonNan, the explicit bit should be added.
> >
> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> > ---
> >  fpu/softfloat-specialize.h |   19 +++++++++++++------
> >  1 files changed, 13 insertions(+), 6 deletions(-)
> >
> > diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
> > index b110187..fb2b5b4 100644
> > --- a/fpu/softfloat-specialize.h
> > +++ b/fpu/softfloat-specialize.h
> > @@ -603,9 +603,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
> >     commonNaNT z;
> >
> >     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
> > -    z.sign = a.high>>15;
> > -    z.low = 0;
> > -    z.high = a.low;
> > +    if ( a.low >> 63 ) {
> > +        z.sign = a.high >> 15;
> > +        z.low = 0;
> > +        z.high = a.low << 1;
> > +    } else {
> > +        z.sign = floatx80_default_nan_high >> 15;
> > +        z.low = 0;
> > +        z.high = floatx80_default_nan_low << 1;
> > +    }
> >     return z;
> >  }
> 
> The intel manuals don't seem to define what a number with non-zero exponent
> field but explicit bit clear actually means. Presumably this (generate a
> default NaN) is what the hardware does if you try to convert such a thing
> to float64?

I tested that on my hardware, on an Intel CPU, and it behaves like that.

> > @@ -624,10 +630,11 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
> >         return z;
> >     }
> >
> > -    if (a.high)
> > -        z.low = a.high;
> > -    else
> > +    if (a.high) {
> > +        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
> > +    } else {
> >         z.low = floatx80_default_nan_low;
> > +    }
> >     z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
> >     return z;
> >  }
> 
> I think the condition here should be "if (a.high >> 1)" -- otherwise we
> might construct an infinity instead (explicit bit 1 but all fraction bits 0).
> Also we are keeping the sign of the input even if we return the default
> NaN. It might be better to start with
>  uint64_t mantissa = a.high >> 1;
> and then roll the 'mantissa == 0' check into the default_nan_mode if().
> 

Correct, good catch. Will fix that in v2.


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

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

* Re: [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants
  2011-04-19 11:07   ` Peter Maydell
@ 2011-04-20  9:05     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:05 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 12:07:26PM +0100, Peter Maydell wrote:
> On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > Add floatx80 constants similarly to float32 or float64.
> >
> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> 
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 
> NB: I didn't actually check you got the ln2 value right :-)
> Also for x86 these constants are stored internally with a 66 bit
> mantissa and then rounded according to the current rounding mode,
> so strictly speaking using these values isn't always the right
> thing, but I think that's being overly picky for now.
> 

Agreed, however it's probably something x86 specific, so that should be
handled in target-i386. That said except on old ARM Netwinder chips, 
only Intel is using floatx80.

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

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

* Re: [Qemu-devel] [PATCH 04/20] softfloat: add pi constants
  2011-04-19 11:10   ` Peter Maydell
@ 2011-04-20  9:05     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:05 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 12:10:48PM +0100, Peter Maydell wrote:
> On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > +#define float64_pi make_float32(0x400921fb54442d18LL)
> 
> This doesn't look quite right :-)
> 

Good catch, fixed.


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

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

* Re: [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases
  2011-04-19 11:57   ` Peter Maydell
@ 2011-04-20  9:21     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:21 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 12:57:23PM +0100, Peter Maydell wrote:
> On 18 April 2011 21:59, Aurelien Jarno <aurelien@aurel32.net> wrote:
> 
> > @@ -6349,6 +6352,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
> >     else if ( aSig == 0 )
> >         return a;
> >
> > +    if (n > 0x80) {
> > +        n = 0x80;
> > +    } else if (n < -0x80) {
> > +        n = -0x80;
> > +    }
> > +
> >     aExp += n - 1;
> >     aSig <<= 7;
> >     return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
> 
> I don't think your if() condition is right here. Consider the
> float32 00800000 (1.0 * 2 ^ -126 ; the smallest possible normalised
> number); you can multiply this by, say, 2^253, without overflowing
> to infinity. However your if() here means we'll incorrectly
> compute the result of multiplying by 2^128 instead. s/0x80/0x200/
> should work.
> 

Correct, will be fixed in the next version.


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

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

* Re: [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions
  2011-04-19 12:42   ` Peter Maydell
@ 2011-04-20  9:22     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:22 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 01:42:00PM +0100, Peter Maydell wrote:
> On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> 
> > @@ -511,4 +530,11 @@ int floatx80_is_quiet_nan( floatx80 a1 )
> >     return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( u.i.low<<1 );
> >  }
> >
> > +int floatx80_is_any_nan( floatx80 a1 )
> > +{
> > +    floatx80u u;
> > +    u.f = a1;
> > +    return ((u.i.high & 0x7FFF) == 0x7FFF) && ( u.i.low<<1 );
> > +}
> > +
> >  #endif
> 
> As you can just see from the context, the new function is
> actually identical to the existing floatx80_is_quiet_nan(),
> but the latter is wrong, not this patch :-)
> 
> Nobody seems to use floatx80_is_quiet_nan() so if we're just
> going to nuke softfloat-native shortly there's no point fixing
> it I guess.
> 

IIRC, we already discovered that when changing the name of the nan()
functions. I also don't plan to fix it, it's one more reason to kill
softfloat-native.


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

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

* Re: [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() wrt softfloat
  2011-04-19 17:06   ` Peter Maydell
@ 2011-04-20  9:37     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:37 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 06:06:57PM +0100, Peter Maydell wrote:
> On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> > ---
> >  target-i386/op_helper.c |    7 ++++---
> >  1 files changed, 4 insertions(+), 3 deletions(-)
> >
> > diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
> > index f614893..7dddd37 100644
> > --- a/target-i386/op_helper.c
> > +++ b/target-i386/op_helper.c
> > @@ -3920,9 +3920,10 @@ void helper_fbld_ST0(target_ulong ptr)
> >         v = ldub(ptr + i);
> >         val = (val * 100) + ((v >> 4) * 10) + (v & 0xf);
> >     }
> > -    tmp = val;
> > -    if (ldub(ptr + 9) & 0x80)
> > -        tmp = -tmp;
> > +    if (ldub(ptr + 9) & 0x80) {
> > +        val = -val;
> > +    }
> > +    tmp = int64_to_floatx(val, &env->fp_status);
> >     fpush();
> >     ST0 = tmp;
> >  }
> 
> This doesn't do the right thing for -0 (should generate -0,
> not +0). I think:
> 
>  tmp = int64_to_floatx(val, &env->fp_status);
>  if (ldub(ptr + 9) & 0x80) {
>      floatx_chs(tmp);
>  }
> 
> ought to do the right thing and work for both softfloat and
> sf-native, but I haven't tested it.
> 

Good catch, this solution works. Thanks.

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

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

* Re: [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() wrt softfloat
  2011-04-19 17:11   ` Peter Maydell
@ 2011-04-20  9:37     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:37 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 06:11:37PM +0100, Peter Maydell wrote:
> On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > +++ b/target-i386/op_helper.c
> > @@ -3440,9 +3440,10 @@ static void fpu_set_exception(int mask)
> >
> >  static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b)
> >  {
> > -    if (b == 0.0)
> > +    if (floatx_is_zero(b)) {
> >         fpu_set_exception(FPUS_ZE);
> > -    return a / b;
> > +    }
> > +    return floatx_div(a, b, &env->fp_status);
> >  }
> 
> When we get rid of softfloat-native we should be able to just
> use softfloat's flag-raising code and get rid of this special
> case of zero, right?

Yes, this is already in my next series adding exception support.

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

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

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

* Re: [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat
  2011-04-19 17:37   ` Peter Maydell
@ 2011-04-20  9:41     ` Aurelien Jarno
  0 siblings, 0 replies; 49+ messages in thread
From: Aurelien Jarno @ 2011-04-20  9:41 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On Tue, Apr 19, 2011 at 06:37:14PM +0100, Peter Maydell wrote:
> On 18 April 2011 22:00, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > +#include <math.h>
> 
> Why does this patch need this? I couldn't see anywhere where
> the patch added calls to math functions we weren't calling before,
> or did I miss one?

Because softloat-native.h include it, but not softfloat.h.

> >  void helper_fptan(void)
> >  {
> > -    CPU86_LDouble fptemp;
> > +    double fptemp = CPU86_LDouble_to_double(ST0);
> >
> > -    fptemp = ST0;
> >     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
> >         env->fpus |= 0x400;
> >     } else {
> > -        ST0 = tan(fptemp);
> > +        fptemp = tan(fptemp);
> > +        ST0 = double_to_CPU86_LDouble(fptemp);
> >         fpush();
> > -        ST0 = 1.0;
> > +        ST0 = double_to_CPU86_LDouble(1.0);
> 
> You could just say:
>    ST0 = floatx_one;
> 

Correct, will fix that.

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

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

end of thread, other threads:[~2011-04-20  9:52 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-18 20:59 [Qemu-devel] [PATCH 00/20] target-i386 conversion to softfloat Aurelien Jarno
2011-04-18 20:59 ` [Qemu-devel] [PATCH 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
2011-04-19 10:53   ` Peter Maydell
2011-04-20  9:02     ` Aurelien Jarno
2011-04-18 20:59 ` [Qemu-devel] [PATCH 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
2011-04-19 10:55   ` Peter Maydell
2011-04-18 20:59 ` [Qemu-devel] [PATCH 03/20] softfloat: add floatx80 constants Aurelien Jarno
2011-04-19 11:07   ` Peter Maydell
2011-04-20  9:05     ` Aurelien Jarno
2011-04-18 20:59 ` [Qemu-devel] [PATCH 04/20] softfloat: add pi constants Aurelien Jarno
2011-04-19 11:10   ` Peter Maydell
2011-04-20  9:05     ` Aurelien Jarno
2011-04-18 20:59 ` [Qemu-devel] [PATCH 05/20] softfloat-native: add a few constant values Aurelien Jarno
2011-04-19 11:12   ` Peter Maydell
2011-04-18 20:59 ` [Qemu-devel] [PATCH 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
2011-04-19 11:16   ` Peter Maydell
2011-04-18 20:59 ` [Qemu-devel] [PATCH 07/20] softfloat: fix float*_scalnb() corner cases Aurelien Jarno
2011-04-19 11:57   ` Peter Maydell
2011-04-20  9:21     ` Aurelien Jarno
2011-04-18 21:00 ` [Qemu-devel] [PATCH 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
2011-04-19 12:35   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
2011-04-19 12:42   ` Peter Maydell
2011-04-20  9:22     ` Aurelien Jarno
2011-04-18 21:00 ` [Qemu-devel] [PATCH 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
2011-04-19 16:57   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 11/20] target-i386: fix helper_flbd_ST0() " Aurelien Jarno
2011-04-19 17:06   ` Peter Maydell
2011-04-20  9:37     ` Aurelien Jarno
2011-04-18 21:00 ` [Qemu-devel] [PATCH 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
2011-04-19 17:46   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
2011-04-19 17:11   ` Peter Maydell
2011-04-20  9:37     ` Aurelien Jarno
2011-04-18 21:00 ` [Qemu-devel] [PATCH 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
2011-04-19 17:13   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
2011-04-19 17:20   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
2011-04-19 17:31   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
2011-04-19 17:37   ` Peter Maydell
2011-04-20  9:41     ` Aurelien Jarno
2011-04-18 21:00 ` [Qemu-devel] [PATCH 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
2011-04-19 17:41   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 19/20] target-i386: fix constants " Aurelien Jarno
2011-04-19 17:26   ` Peter Maydell
2011-04-18 21:00 ` [Qemu-devel] [PATCH 20/20] target-i386: switch to softfloat Aurelien Jarno
2011-04-19 17:28   ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.