All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE ***
@ 2011-04-20 10:11 Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
                   ` (19 more replies)
  0 siblings, 20 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 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_fbld_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                  |    9 +--
 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, 342 insertions(+), 116 deletions(-)

-- 
1.7.2.3

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

* [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:35   ` Peter Maydell
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 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(-)

v1 -> v2: fix wrong condition that may create an infinity instead of a NaN.

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b110187..29e30ce 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 >> 1) {
+        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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 02/20] softfloat: fix floatx80_is_infinity()
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 03/20] softfloat: add floatx80 constants Aurelien Jarno
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

With floatx80, the explicit bit is set for infinity.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 03/20] softfloat: add floatx80 constants
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 04/20] softfloat: add pi constants Aurelien Jarno
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Add floatx80 constants similarly to float32 or float64.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 04/20] softfloat: add pi constants
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (2 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 03/20] softfloat: add floatx80 constants Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:40   ` Peter Maydell
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 05/20] softfloat-native: add a few constant values Aurelien Jarno
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 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(-)

v1 -> v2: fix typo creating a float64 constant with make_float32

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 90e0c41..7b3b88f 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_float64(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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 05/20] softfloat-native: add a few constant values
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (3 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 04/20] softfloat: add pi constants Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 06/20] softfloat: add floatx80_compare*() functions
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (4 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 05/20] softfloat-native: add a few constant values Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 07/20] softfloat: fix float*_scalnb() corner cases Aurelien Jarno
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 7b3b88f..5eff085 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 07/20] softfloat: fix float*_scalnb() corner cases
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (5 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:40   ` Peter Maydell
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 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(-)

v1 -> v2: fix condition for float32

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4368069..baba1dc 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 > 0x200) {
+        n = 0x200;
+    } else if (n < -0x200) {
+        n = -0x200;
+    }
+
     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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 08/20] softfloat-native: fix float*_scalbn() functions
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (6 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 07/20] softfloat: fix float*_scalnb() corner cases Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 09/20] softfloat-native: add float*_is_any_nan() functions
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (7 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

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

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 10/20] target-i386: fix helper_fscale() wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (8 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
@ 2011-04-20 10:11 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 11/20] target-i386: fix helper_fbld_ST0() " Aurelien Jarno
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:11 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.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 11/20] target-i386: fix helper_fbld_ST0() wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (9 preceding siblings ...)
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:41   ` Peter Maydell
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 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(-)

v1 -> v2: fix handling of -0

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f614893..22cb549 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;
+    tmp = int64_to_floatx(val, &env->fp_status);
+    if (ldub(ptr + 9) & 0x80) {
+        floatx_chs(tmp);
+    }
     fpush();
     ST0 = tmp;
 }
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH v2 12/20] target-i386: fix helper_fxtract() wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (10 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 11/20] target-i386: fix helper_fbld_ST0() " Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 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.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 22cb549..a4bf734 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 13/20] target-i386: fix helper_fdiv() wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (11 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 a4bf734..b22462f 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 14/20] target-i386: fix helper_fsqrt() wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (12 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 b22462f..02edfea 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (13 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 02edfea..b47d825 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 16/20] target-i386: add CPU86_LDouble <-> double conversion functions
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (14 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 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.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 b47d825..d9c8c1b 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (15 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:41   ` Peter Maydell
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 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(-)

v1 -> v2: use floatx_one instead of double_to_CPU86_LDouble(1.0)

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index d9c8c1b..f18c573 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 = floatx_one;
         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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 18/20] target-i386: fix helper_fprem() and helper_fprem1() wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (16 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 19/20] target-i386: fix constants " Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 20/20] target-i386: switch to softfloat Aurelien Jarno
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 f18c573..6a536e2 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 19/20] target-i386: fix constants wrt softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (17 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 20/20] target-i386: switch to softfloat Aurelien Jarno
  19 siblings, 0 replies; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 6a536e2..49043bf 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] 29+ messages in thread

* [Qemu-devel] [PATCH v2 20/20] target-i386: switch to softfloat
  2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
                   ` (18 preceding siblings ...)
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 19/20] target-i386: fix constants " Aurelien Jarno
@ 2011-04-20 10:12 ` Aurelien Jarno
  2011-04-20 10:42   ` Peter Maydell
  19 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 10:12 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 |    9 +--------
 1 files changed, 1 insertions(+), 8 deletions(-)

v1 -> v2: remove case.

diff --git a/configure b/configure
index da2da04..f2eab30 100755
--- a/configure
+++ b/configure
@@ -3275,14 +3275,7 @@ if test ! -z "$gdb_xml_files" ; then
   echo "TARGET_XML_FILES=$list" >> $config_target_mak
 fi
 
-case "$target_arch2" in
-  i386|x86_64)
-    echo "CONFIG_NOSOFTFLOAT=y" >> $config_target_mak
-    ;;
-  *)
-    echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
-    ;;
-esac
+echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak
 
 if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
   echo "TARGET_HAS_BFLT=y" >> $config_target_mak
-- 
1.7.2.3

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

* Re: [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
@ 2011-04-20 10:35   ` Peter Maydell
  2011-04-20 11:24     ` [Qemu-devel] [PATCH v3 " Aurelien Jarno
  0 siblings, 1 reply; 29+ messages in thread
From: Peter Maydell @ 2011-04-20 10:35 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 20 April 2011 11:11, Aurelien Jarno <aurelien@aurel32.net> wrote:
> @@ -624,10 +630,11 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
>         return z;
>     }
>
> -    if (a.high)
> -        z.low = a.high;
> -    else
> +    if (a.high >> 1) {
> +        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
> +    } else {
>         z.low = floatx80_default_nan_low;
> +    }
>     z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
>     return z;
>  }

This is still retaining the sign bit from the input if it generates
a default NaN because the mantissa would have been zero. This isn't
consistent with the commonNaNToFloat64/32, which just return the
float64/32_default_nan with whatever sign it has.

-- PMM

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

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

On 20 April 2011 11:11, Aurelien Jarno <aurelien@aurel32.net> wrote:
> 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(-)
>
> v1 -> v2: fix typo creating a float64 constant with make_float32

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

-- PMM

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

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

On 20 April 2011 11:11, Aurelien Jarno <aurelien@aurel32.net> wrote:
> 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(-)
>
> v1 -> v2: fix condition for float32

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

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 11/20] target-i386: fix helper_fbld_ST0() wrt softfloat
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 11/20] target-i386: fix helper_fbld_ST0() " Aurelien Jarno
@ 2011-04-20 10:41   ` Peter Maydell
  0 siblings, 0 replies; 29+ messages in thread
From: Peter Maydell @ 2011-04-20 10:41 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 20 April 2011 11:12, 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(-)
>
> v1 -> v2: fix handling of -0

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

-- PMM

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

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

On 20 April 2011 11:12, Aurelien Jarno <aurelien@aurel32.net> wrote:
> 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(-)
>
> v1 -> v2: use floatx_one instead of double_to_CPU86_LDouble(1.0)

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

-- PMM

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

* Re: [Qemu-devel] [PATCH v2 20/20] target-i386: switch to softfloat
  2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 20/20] target-i386: switch to softfloat Aurelien Jarno
@ 2011-04-20 10:42   ` Peter Maydell
  0 siblings, 0 replies; 29+ messages in thread
From: Peter Maydell @ 2011-04-20 10:42 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 20 April 2011 11:12, Aurelien Jarno <aurelien@aurel32.net> wrote:
> 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 |    9 +--------
>  1 files changed, 1 insertions(+), 8 deletions(-)
>
> v1 -> v2: remove case.

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

-- PMM

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

* [Qemu-devel] [PATCH v3 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-20 10:35   ` Peter Maydell
@ 2011-04-20 11:24     ` Aurelien Jarno
  2011-04-20 11:28       ` Peter Maydell
  0 siblings, 1 reply; 29+ messages in thread
From: Aurelien Jarno @ 2011-04-20 11:24 UTC (permalink / raw)
  To: qemu-devel

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 |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

v1 -> v2: fix wrong condition that may create an infinity instead of a
          NaN
v2 -> v3: don't change the sign of the default NaN.

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b110187..9d68aae 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,11 +630,14 @@ static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
         return z;
     }
 
-    if (a.high)
-        z.low = a.high;
-    else
+    if (a.high >> 1) {
+        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
+        z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+    } else {
         z.low = floatx80_default_nan_low;
-    z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+        z.high = floatx80_default_nan_high;
+    }
+
     return z;
 }
 
-- 
1.7.2.3

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

* Re: [Qemu-devel] [PATCH v3 01/20] softfloat: fix floatx80 handling of NaN
  2011-04-20 11:24     ` [Qemu-devel] [PATCH v3 " Aurelien Jarno
@ 2011-04-20 11:28       ` Peter Maydell
  0 siblings, 0 replies; 29+ messages in thread
From: Peter Maydell @ 2011-04-20 11:28 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 20 April 2011 12:24, 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 |   23 ++++++++++++++++-------
>  1 files changed, 16 insertions(+), 7 deletions(-)
>
> v1 -> v2: fix wrong condition that may create an infinity instead of a
>          NaN
> v2 -> v3: don't change the sign of the default NaN.

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

-- PMM

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

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

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