All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/4] ARM: fix Neon VRECPE and VRSQRTE instructions.
@ 2011-02-18 14:49 Christophe Lyon
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h Christophe Lyon
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Christophe Lyon @ 2011-02-18 14:49 UTC (permalink / raw)
  To: qemu-devel

These 4 patches fix the ARM Neon vrecpe and vrsqrte instructions by
matching the algorithms descibed in the ARM ARM.

With these patches, qemu passes my ARM/Neon tests.

Compared to v3, I have split patch #1 into 2 pieces (#1 and #2 here),
and fixed comments from Peter.

Patch #1 modifies softfloat by exporting floatXX_default_nan, i.e. moving all these definitions from softfloat-specialize.h to softfloat.h

Patch #2 introduces a new utility function float32_set_sign() to help
return the right special values (-0, -infinity), as well as new
constants: float32_infinity, float64_half, float64_256 and
float64_512.

Patch #3 uses these newly exported values and uses the VRECPE
algorithm described in the ARM ARM.

Patch #4 uses these newly exported values and uses the VRSQRTE
algorithm described in the ARM ARM.

Thanks to Peter for his careful reviews.

Christophe Lyon (4):
  softfloat: move all default NaN definitions to softfloat.h.
  softfloat: add float32_set_sign(), float32_infinity, float64_half,
    float64_256 and float64_512.
  target-arm: fix support for VRECPE.
  target-arm: fix support for VRSQRTE.

 fpu/softfloat-specialize.h |   68 ---------------
 fpu/softfloat.h            |   78 +++++++++++++++++
 target-arm/helper.c        |  204 +++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 260 insertions(+), 90 deletions(-)

-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h.
  2011-02-18 14:49 [Qemu-devel] [PATCH v4 0/4] ARM: fix Neon VRECPE and VRSQRTE instructions Christophe Lyon
@ 2011-02-18 14:49 ` Christophe Lyon
  2011-02-20 21:49   ` Aurelien Jarno
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512 Christophe Lyon
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Christophe Lyon @ 2011-02-18 14:49 UTC (permalink / raw)
  To: qemu-devel

These special values are needed to implement some helper functions,
which return/use these values in some cases.

Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
---
 fpu/softfloat-specialize.h |   68 -------------------------------------------
 fpu/softfloat.h            |   69 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 68 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 2d025bf..adc5ada 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -30,12 +30,6 @@ these four paragraphs for those parts of this code that are retained.
 
 =============================================================================*/
 
-#if defined(TARGET_MIPS) || defined(TARGET_SH4)
-#define SNAN_BIT_IS_ONE		1
-#else
-#define SNAN_BIT_IS_ONE		0
-#endif
-
 /*----------------------------------------------------------------------------
 | Raises the exceptions specified by `flags'.  Floating-point traps can be
 | defined here if desired.  It is currently not possible for such a trap
@@ -57,17 +51,6 @@ typedef struct {
 } commonNaNT;
 
 /*----------------------------------------------------------------------------
-| The pattern for a default generated half-precision NaN.
-*----------------------------------------------------------------------------*/
-#if defined(TARGET_ARM)
-#define float16_default_nan make_float16(0x7E00)
-#elif SNAN_BIT_IS_ONE
-#define float16_default_nan make_float16(0x7DFF)
-#else
-#define float16_default_nan make_float16(0xFE00)
-#endif
-
-/*----------------------------------------------------------------------------
 | Returns 1 if the half-precision floating-point value `a' is a quiet
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
@@ -158,19 +141,6 @@ static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
 }
 
 /*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-#if defined(TARGET_SPARC)
-#define float32_default_nan make_float32(0x7FFFFFFF)
-#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
-#define float32_default_nan make_float32(0x7FC00000)
-#elif SNAN_BIT_IS_ONE
-#define float32_default_nan make_float32(0x7FBFFFFF)
-#else
-#define float32_default_nan make_float32(0xFFC00000)
-#endif
-
-/*----------------------------------------------------------------------------
 | Returns 1 if the single-precision floating-point value `a' is a quiet
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
@@ -413,19 +383,6 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
 }
 
 /*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-#if defined(TARGET_SPARC)
-#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
-#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
-#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
-#elif SNAN_BIT_IS_ONE
-#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
-#else
-#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
-#endif
-
-/*----------------------------------------------------------------------------
 | Returns 1 if the double-precision floating-point value `a' is a quiet
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
@@ -564,19 +521,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.  The
-| `high' and `low' values hold the most- and least-significant bits,
-| respectively.
-*----------------------------------------------------------------------------*/
-#if SNAN_BIT_IS_ONE
-#define floatx80_default_nan_high 0x7FFF
-#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
-#else
-#define floatx80_default_nan_high 0xFFFF
-#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
-#endif
-
-/*----------------------------------------------------------------------------
 | Returns 1 if the extended double-precision floating-point value `a' is a
 | quiet NaN; otherwise returns 0. This slightly differs from the same
 | function for other types as floatx80 has an explicit bit.
@@ -728,18 +672,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
 #ifdef FLOAT128
 
 /*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.  The `high' and
-| `low' values hold the most- and least-significant bits, respectively.
-*----------------------------------------------------------------------------*/
-#if SNAN_BIT_IS_ONE
-#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
-#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
-#else
-#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
-#define float128_default_nan_low  LIT64( 0x0000000000000000 )
-#endif
-
-/*----------------------------------------------------------------------------
 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
 | NaN; otherwise returns 0.
 *----------------------------------------------------------------------------*/
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index e57ee1e..f34a938 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -77,6 +77,12 @@ typedef int64_t sbits64;
 #define LIT64( a ) a##LL
 #define INLINE static inline
 
+#if defined(TARGET_MIPS) || defined(TARGET_SH4)
+#define SNAN_BIT_IS_ONE		1
+#else
+#define SNAN_BIT_IS_ONE		0
+#endif
+
 /*----------------------------------------------------------------------------
 | The macro `FLOATX80' must be defined to enable the extended double-precision
 | floating-point format `floatx80'.  If this macro is not defined, the
@@ -278,6 +284,17 @@ int float16_is_signaling_nan( float16 );
 float16 float16_maybe_silence_nan( float16 );
 
 /*----------------------------------------------------------------------------
+| The pattern for a default generated half-precision NaN.
+*----------------------------------------------------------------------------*/
+#if defined(TARGET_ARM)
+#define float16_default_nan make_float16(0x7E00)
+#elif SNAN_BIT_IS_ONE
+#define float16_default_nan make_float16(0x7DFF)
+#else
+#define float16_default_nan make_float16(0xFE00)
+#endif
+
+/*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int float32_to_int16_round_to_zero( float32 STATUS_PARAM );
@@ -366,6 +383,20 @@ INLINE int float32_is_zero_or_denormal(float32 a)
 #define float32_one make_float32(0x3f800000)
 #define float32_ln2 make_float32(0x3f317218)
 
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated single-precision NaN.
+*----------------------------------------------------------------------------*/
+#if defined(TARGET_SPARC)
+#define float32_default_nan make_float32(0x7FFFFFFF)
+#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
+#define float32_default_nan make_float32(0x7FC00000)
+#elif SNAN_BIT_IS_ONE
+#define float32_default_nan make_float32(0x7FBFFFFF)
+#else
+#define float32_default_nan make_float32(0xFFC00000)
+#endif
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
@@ -452,6 +483,19 @@ INLINE int float64_is_any_nan(float64 a)
 #define float64_one make_float64(0x3ff0000000000000LL)
 #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
 
+/*----------------------------------------------------------------------------
+| The pattern for a default generated double-precision NaN.
+*----------------------------------------------------------------------------*/
+#if defined(TARGET_SPARC)
+#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
+#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
+#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
+#elif SNAN_BIT_IS_ONE
+#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
+#else
+#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
+#endif
+
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
@@ -520,6 +564,19 @@ INLINE int floatx80_is_any_nan(floatx80 a)
     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
 }
 
+/*----------------------------------------------------------------------------
+| The pattern for a default generated extended double-precision NaN.  The
+| `high' and `low' values hold the most- and least-significant bits,
+| respectively.
+*----------------------------------------------------------------------------*/
+#if SNAN_BIT_IS_ONE
+#define floatx80_default_nan_high 0x7FFF
+#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
+#else
+#define floatx80_default_nan_high 0xFFFF
+#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
+#endif
+
 #endif
 
 #ifdef FLOAT128
@@ -593,6 +650,18 @@ INLINE int float128_is_any_nan(float128 a)
         ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
 }
 
+/*----------------------------------------------------------------------------
+| The pattern for a default generated quadruple-precision NaN.  The `high' and
+| `low' values hold the most- and least-significant bits, respectively.
+*----------------------------------------------------------------------------*/
+#if SNAN_BIT_IS_ONE
+#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
+#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
+#else
+#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
+#define float128_default_nan_low  LIT64( 0x0000000000000000 )
+#endif
+
 #endif
 
 #else /* CONFIG_SOFTFLOAT */
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512.
  2011-02-18 14:49 [Qemu-devel] [PATCH v4 0/4] ARM: fix Neon VRECPE and VRSQRTE instructions Christophe Lyon
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h Christophe Lyon
@ 2011-02-18 14:49 ` Christophe Lyon
  2011-02-20 21:52   ` Aurelien Jarno
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 3/4] target-arm: fix support for VRECPE Christophe Lyon
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 4/4] target-arm: fix support for VRSQRTE Christophe Lyon
  3 siblings, 1 reply; 10+ messages in thread
From: Christophe Lyon @ 2011-02-18 14:49 UTC (permalink / raw)
  To: qemu-devel

These constants and utility function are needed to implement some
helpers. Defining constants avoids the need to re-compute them at
runtime.

Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
---
 fpu/softfloat.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index f34a938..9bd4a50 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -379,9 +379,15 @@ INLINE int float32_is_zero_or_denormal(float32 a)
     return (float32_val(a) & 0x7f800000) == 0;
 }
 
+INLINE float32 float32_set_sign(float32 a, int sign)
+{
+    return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
+}
+
 #define float32_zero make_float32(0)
 #define float32_one make_float32(0x3f800000)
 #define float32_ln2 make_float32(0x3f317218)
+#define float32_infinity make_float32(0x7f800000)
 
 
 /*----------------------------------------------------------------------------
@@ -482,6 +488,9 @@ INLINE int float64_is_any_nan(float64 a)
 #define float64_zero make_float64(0)
 #define float64_one make_float64(0x3ff0000000000000LL)
 #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
+#define float64_half make_float64(0x3fe0000000000000LL)
+#define float64_256 make_float64(0x4070000000000000LL)
+#define float64_512 make_float64(0x4080000000000000LL)
 
 /*----------------------------------------------------------------------------
 | The pattern for a default generated double-precision NaN.
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 3/4] target-arm: fix support for VRECPE.
  2011-02-18 14:49 [Qemu-devel] [PATCH v4 0/4] ARM: fix Neon VRECPE and VRSQRTE instructions Christophe Lyon
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h Christophe Lyon
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512 Christophe Lyon
@ 2011-02-18 14:49 ` Christophe Lyon
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 4/4] target-arm: fix support for VRSQRTE Christophe Lyon
  3 siblings, 0 replies; 10+ messages in thread
From: Christophe Lyon @ 2011-02-18 14:49 UTC (permalink / raw)
  To: qemu-devel

Now use the same algorithm as described in the ARM ARM.

Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
---
 target-arm/helper.c |   83 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7f63a28..af8b067 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2687,13 +2687,67 @@ float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
 
 /* NEON helpers.  */
 
-/* TODO: The architecture specifies the value that the estimate functions
-   should return.  We return the exact reciprocal/root instead.  */
+/* The algorithm that must be used to calculate the estimate
+ * is specified by the ARM ARM.
+ */
+static float64 recip_estimate(float64 a, CPUState *env)
+{
+    float_status *s = &env->vfp.standard_fp_status;
+    /* q = (int)(a * 512.0) */
+    float64 q = float64_mul(float64_512, a, s);
+    int64_t q_int = float64_to_int64_round_to_zero(q, s);
+
+    /* r = 1.0 / (((double)q + 0.5) / 512.0) */
+    q = int64_to_float64(q_int, s);
+    q = float64_add(q, float64_half, s);
+    q = float64_div(q, float64_512, s);
+    q = float64_div(float64_one, q, s);
+
+    /* s = (int)(256.0 * r + 0.5) */
+    q = float64_mul(q, float64_256, s);
+    q = float64_add(q, float64_half, s);
+    q_int = float64_to_int64_round_to_zero(q, s);
+
+    /* return (double)s / 256.0 */
+    return float64_div(int64_to_float64(q_int, s), float64_256, s);
+}
+
 float32 HELPER(recpe_f32)(float32 a, CPUState *env)
 {
-    float_status *s = &env->vfp.fp_status;
-    float32 one = int32_to_float32(1, s);
-    return float32_div(one, a, s);
+    float_status *s = &env->vfp.standard_fp_status;
+    float64 f64;
+    uint32_t val32 = float32_val(a);
+
+    int result_exp;
+    int a_exp = (val32  & 0x7f800000) >> 23;
+    int sign = val32 & 0x80000000;
+
+    if (float32_is_any_nan(a)) {
+        if (float32_is_signaling_nan(a)) {
+            float_raise(float_flag_invalid, s);
+        }
+        return float32_maybe_silence_nan(a);
+    } else if (float32_is_infinity(a)) {
+        return float32_set_sign(float32_zero, float32_is_neg(a));
+    } else if (float32_is_zero_or_denormal(a)) {
+        float_raise(float_flag_divbyzero, s);
+        return float32_set_sign(float32_infinity, float32_is_neg(a));
+    } else if (a_exp >= 253) {
+        float_raise(float_flag_underflow, s);
+        return float32_set_sign(float32_zero, float32_is_neg(a));
+    }
+
+    f64 = make_float64((0x3feULL << 52)
+                       | ((int64_t)(val32 & 0x7fffff) << 29));
+
+    result_exp = 253 - a_exp;
+
+    f64 = recip_estimate(f64, env);
+
+    val32 = sign
+        | ((result_exp & 0xff) << 23)
+        | ((float64_val(f64) >> 29) & 0x7fffff);
+    return make_float32(val32);
 }
 
 float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
@@ -2705,13 +2759,18 @@ float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
 
 uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
 {
-    float_status *s = &env->vfp.fp_status;
-    float32 tmp;
-    tmp = int32_to_float32(a, s);
-    tmp = float32_scalbn(tmp, -32, s);
-    tmp = helper_recpe_f32(tmp, env);
-    tmp = float32_scalbn(tmp, 31, s);
-    return float32_to_int32(tmp, s);
+    float64 f64;
+
+    if ((a & 0x80000000) == 0) {
+        return 0xffffffff;
+    }
+
+    f64 = make_float64((0x3feULL << 52)
+                       | ((int64_t)(a & 0x7fffffff) << 21));
+
+    f64 = recip_estimate (f64, env);
+
+    return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
 }
 
 uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
-- 
1.7.2.3

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

* [Qemu-devel] [PATCH 4/4] target-arm: fix support for VRSQRTE.
  2011-02-18 14:49 [Qemu-devel] [PATCH v4 0/4] ARM: fix Neon VRECPE and VRSQRTE instructions Christophe Lyon
                   ` (2 preceding siblings ...)
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 3/4] target-arm: fix support for VRECPE Christophe Lyon
@ 2011-02-18 14:49 ` Christophe Lyon
  3 siblings, 0 replies; 10+ messages in thread
From: Christophe Lyon @ 2011-02-18 14:49 UTC (permalink / raw)
  To: qemu-devel

Now use the same algorithm as described in the ARM ARM.

Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
---
 target-arm/helper.c |  121 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 111 insertions(+), 10 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index af8b067..d770b5c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2750,11 +2750,104 @@ float32 HELPER(recpe_f32)(float32 a, CPUState *env)
     return make_float32(val32);
 }
 
+/* The algorithm that must be used to calculate the estimate
+ * is specified by the ARM ARM.
+ */
+static float64 recip_sqrt_estimate(float64 a, CPUState *env)
+{
+    float_status *s = &env->vfp.standard_fp_status;
+    float64 q;
+    int64_t q_int;
+
+    if (float64_lt(a, float64_half, s)) {
+        /* range 0.25 <= a < 0.5 */
+
+        /* a in units of 1/512 rounded down */
+        /* q0 = (int)(a * 512.0);  */
+        q = float64_mul(float64_512, a, s);
+        q_int = float64_to_int64_round_to_zero(q, s);
+
+        /* reciprocal root r */
+        /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0);  */
+        q = int64_to_float64(q_int, s);
+        q = float64_add(q, float64_half, s);
+        q = float64_div(q, float64_512, s);
+        q = float64_sqrt(q, s);
+        q = float64_div(float64_one, q, s);
+    } else {
+        /* range 0.5 <= a < 1.0 */
+
+        /* a in units of 1/256 rounded down */
+        /* q1 = (int)(a * 256.0); */
+        q = float64_mul(float64_256, a, s);
+        int64_t q_int = float64_to_int64_round_to_zero(q, s);
+
+        /* reciprocal root r */
+        /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */
+        q = int64_to_float64(q_int, s);
+        q = float64_add(q, float64_half, s);
+        q = float64_div(q, float64_256, s);
+        q = float64_sqrt(q, s);
+        q = float64_div(float64_one, q, s);
+    }
+    /* r in units of 1/256 rounded to nearest */
+    /* s = (int)(256.0 * r + 0.5); */
+
+    q = float64_mul(q, float64_256,s );
+    q = float64_add(q, float64_half, s);
+    q_int = float64_to_int64_round_to_zero(q, s);
+
+    /* return (double)s / 256.0;*/
+    return float64_div(int64_to_float64(q_int, s), float64_256, s);
+}
+
 float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
 {
-    float_status *s = &env->vfp.fp_status;
-    float32 one = int32_to_float32(1, s);
-    return float32_div(one, float32_sqrt(a, s), s);
+    float_status *s = &env->vfp.standard_fp_status;
+    int result_exp;
+    float64 f64;
+    uint32_t val;
+    uint64_t val64;
+
+    val = float32_val(a);
+
+    if (float32_is_any_nan(a)) {
+        if (float32_is_signaling_nan(a)) {
+            float_raise(float_flag_invalid, s);
+        }
+        return float32_maybe_silence_nan(a);
+    } else if (float32_is_zero_or_denormal(a)) {
+        float_raise(float_flag_divbyzero, s);
+        return float32_set_sign(float32_infinity, float32_is_neg(a));
+    } else if (float32_is_neg(a)) {
+        float_raise(float_flag_invalid, s);
+        return float32_default_nan;
+    } else if (float32_is_infinity(a)) {
+        return float32_zero;
+    }
+
+    /* Normalize to a double-precision value between 0.25 and 1.0,
+     * preserving the parity of the exponent.  */
+    if ((val & 0x800000) == 0) {
+        f64 = make_float64(((uint64_t)(val & 0x80000000) << 32)
+                           | (0x3feULL << 52)
+                           | ((uint64_t)(val & 0x7fffff) << 29));
+    } else {
+        f64 = make_float64(((uint64_t)(val & 0x80000000) << 32)
+                           | (0x3fdULL << 52)
+                           | ((uint64_t)(val & 0x7fffff) << 29));
+    }
+
+    result_exp = (380 - ((val & 0x7f800000) >> 23)) / 2;
+
+    f64 = recip_sqrt_estimate(f64, env);
+
+    val64 = float64_val(f64);
+
+    val = ((val64 >> 63)  & 0x80000000)
+        | ((result_exp & 0xff) << 23)
+        | ((val64 >> 29)  & 0x7fffff);
+    return make_float32(val);
 }
 
 uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
@@ -2775,13 +2868,21 @@ uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
 
 uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
 {
-    float_status *s = &env->vfp.fp_status;
-    float32 tmp;
-    tmp = int32_to_float32(a, s);
-    tmp = float32_scalbn(tmp, -32, s);
-    tmp = helper_rsqrte_f32(tmp, env);
-    tmp = float32_scalbn(tmp, 31, s);
-    return float32_to_int32(tmp, s);
+    float64 f64;
+
+    if ((a & 0xc0000000) == 0) return 0xffffffff;
+
+    if (a & 0x80000000) {
+        f64 = make_float64((0x3feULL << 52)
+                           | ((uint64_t)(a & 0x7fffffff) << 21));
+    } else { /* bits 31-30 == '01' */
+        f64 = make_float64((0x3fdULL << 52)
+                           | ((uint64_t)(a & 0x3fffffff) << 22));
+    }
+
+    f64 = recip_sqrt_estimate(f64, env);
+
+    return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
 }
 
 void HELPER(set_teecr)(CPUState *env, uint32_t val)
-- 
1.7.2.3

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

* Re: [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h.
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h Christophe Lyon
@ 2011-02-20 21:49   ` Aurelien Jarno
  0 siblings, 0 replies; 10+ messages in thread
From: Aurelien Jarno @ 2011-02-20 21:49 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: qemu-devel

On Fri, Feb 18, 2011 at 03:49:14PM +0100, Christophe Lyon wrote:
> These special values are needed to implement some helper functions,
> which return/use these values in some cases.
> 
> Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
> ---
>  fpu/softfloat-specialize.h |   68 -------------------------------------------
>  fpu/softfloat.h            |   69 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+), 68 deletions(-)
> 
> diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
> index 2d025bf..adc5ada 100644
> --- a/fpu/softfloat-specialize.h
> +++ b/fpu/softfloat-specialize.h
> @@ -30,12 +30,6 @@ these four paragraphs for those parts of this code that are retained.
>  
>  =============================================================================*/
>  
> -#if defined(TARGET_MIPS) || defined(TARGET_SH4)
> -#define SNAN_BIT_IS_ONE		1
> -#else
> -#define SNAN_BIT_IS_ONE		0
> -#endif
> -
>  /*----------------------------------------------------------------------------
>  | Raises the exceptions specified by `flags'.  Floating-point traps can be
>  | defined here if desired.  It is currently not possible for such a trap
> @@ -57,17 +51,6 @@ typedef struct {
>  } commonNaNT;
>  
>  /*----------------------------------------------------------------------------
> -| The pattern for a default generated half-precision NaN.
> -*----------------------------------------------------------------------------*/
> -#if defined(TARGET_ARM)
> -#define float16_default_nan make_float16(0x7E00)
> -#elif SNAN_BIT_IS_ONE
> -#define float16_default_nan make_float16(0x7DFF)
> -#else
> -#define float16_default_nan make_float16(0xFE00)
> -#endif
> -
> -/*----------------------------------------------------------------------------
>  | Returns 1 if the half-precision floating-point value `a' is a quiet
>  | NaN; otherwise returns 0.
>  *----------------------------------------------------------------------------*/
> @@ -158,19 +141,6 @@ static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
>  }
>  
>  /*----------------------------------------------------------------------------
> -| The pattern for a default generated single-precision NaN.
> -*----------------------------------------------------------------------------*/
> -#if defined(TARGET_SPARC)
> -#define float32_default_nan make_float32(0x7FFFFFFF)
> -#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
> -#define float32_default_nan make_float32(0x7FC00000)
> -#elif SNAN_BIT_IS_ONE
> -#define float32_default_nan make_float32(0x7FBFFFFF)
> -#else
> -#define float32_default_nan make_float32(0xFFC00000)
> -#endif
> -
> -/*----------------------------------------------------------------------------
>  | Returns 1 if the single-precision floating-point value `a' is a quiet
>  | NaN; otherwise returns 0.
>  *----------------------------------------------------------------------------*/
> @@ -413,19 +383,6 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
>  }
>  
>  /*----------------------------------------------------------------------------
> -| The pattern for a default generated double-precision NaN.
> -*----------------------------------------------------------------------------*/
> -#if defined(TARGET_SPARC)
> -#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
> -#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
> -#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
> -#elif SNAN_BIT_IS_ONE
> -#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
> -#else
> -#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
> -#endif
> -
> -/*----------------------------------------------------------------------------
>  | Returns 1 if the double-precision floating-point value `a' is a quiet
>  | NaN; otherwise returns 0.
>  *----------------------------------------------------------------------------*/
> @@ -564,19 +521,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
>  #ifdef FLOATX80
>  
>  /*----------------------------------------------------------------------------
> -| The pattern for a default generated extended double-precision NaN.  The
> -| `high' and `low' values hold the most- and least-significant bits,
> -| respectively.
> -*----------------------------------------------------------------------------*/
> -#if SNAN_BIT_IS_ONE
> -#define floatx80_default_nan_high 0x7FFF
> -#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
> -#else
> -#define floatx80_default_nan_high 0xFFFF
> -#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
> -#endif
> -
> -/*----------------------------------------------------------------------------
>  | Returns 1 if the extended double-precision floating-point value `a' is a
>  | quiet NaN; otherwise returns 0. This slightly differs from the same
>  | function for other types as floatx80 has an explicit bit.
> @@ -728,18 +672,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
>  #ifdef FLOAT128
>  
>  /*----------------------------------------------------------------------------
> -| The pattern for a default generated quadruple-precision NaN.  The `high' and
> -| `low' values hold the most- and least-significant bits, respectively.
> -*----------------------------------------------------------------------------*/
> -#if SNAN_BIT_IS_ONE
> -#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
> -#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
> -#else
> -#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
> -#define float128_default_nan_low  LIT64( 0x0000000000000000 )
> -#endif
> -
> -/*----------------------------------------------------------------------------
>  | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
>  | NaN; otherwise returns 0.
>  *----------------------------------------------------------------------------*/
> diff --git a/fpu/softfloat.h b/fpu/softfloat.h
> index e57ee1e..f34a938 100644
> --- a/fpu/softfloat.h
> +++ b/fpu/softfloat.h
> @@ -77,6 +77,12 @@ typedef int64_t sbits64;
>  #define LIT64( a ) a##LL
>  #define INLINE static inline
>  
> +#if defined(TARGET_MIPS) || defined(TARGET_SH4)
> +#define SNAN_BIT_IS_ONE		1
> +#else
> +#define SNAN_BIT_IS_ONE		0
> +#endif
> +
>  /*----------------------------------------------------------------------------
>  | The macro `FLOATX80' must be defined to enable the extended double-precision
>  | floating-point format `floatx80'.  If this macro is not defined, the
> @@ -278,6 +284,17 @@ int float16_is_signaling_nan( float16 );
>  float16 float16_maybe_silence_nan( float16 );
>  
>  /*----------------------------------------------------------------------------
> +| The pattern for a default generated half-precision NaN.
> +*----------------------------------------------------------------------------*/
> +#if defined(TARGET_ARM)
> +#define float16_default_nan make_float16(0x7E00)
> +#elif SNAN_BIT_IS_ONE
> +#define float16_default_nan make_float16(0x7DFF)
> +#else
> +#define float16_default_nan make_float16(0xFE00)
> +#endif
> +
> +/*----------------------------------------------------------------------------
>  | Software IEC/IEEE single-precision conversion routines.
>  *----------------------------------------------------------------------------*/
>  int float32_to_int16_round_to_zero( float32 STATUS_PARAM );
> @@ -366,6 +383,20 @@ INLINE int float32_is_zero_or_denormal(float32 a)
>  #define float32_one make_float32(0x3f800000)
>  #define float32_ln2 make_float32(0x3f317218)
>  
> +
> +/*----------------------------------------------------------------------------
> +| The pattern for a default generated single-precision NaN.
> +*----------------------------------------------------------------------------*/
> +#if defined(TARGET_SPARC)
> +#define float32_default_nan make_float32(0x7FFFFFFF)
> +#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
> +#define float32_default_nan make_float32(0x7FC00000)
> +#elif SNAN_BIT_IS_ONE
> +#define float32_default_nan make_float32(0x7FBFFFFF)
> +#else
> +#define float32_default_nan make_float32(0xFFC00000)
> +#endif
> +
>  /*----------------------------------------------------------------------------
>  | Software IEC/IEEE double-precision conversion routines.
>  *----------------------------------------------------------------------------*/
> @@ -452,6 +483,19 @@ INLINE int float64_is_any_nan(float64 a)
>  #define float64_one make_float64(0x3ff0000000000000LL)
>  #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
>  
> +/*----------------------------------------------------------------------------
> +| The pattern for a default generated double-precision NaN.
> +*----------------------------------------------------------------------------*/
> +#if defined(TARGET_SPARC)
> +#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
> +#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
> +#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
> +#elif SNAN_BIT_IS_ONE
> +#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
> +#else
> +#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
> +#endif
> +
>  #ifdef FLOATX80
>  
>  /*----------------------------------------------------------------------------
> @@ -520,6 +564,19 @@ INLINE int floatx80_is_any_nan(floatx80 a)
>      return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
>  }
>  
> +/*----------------------------------------------------------------------------
> +| The pattern for a default generated extended double-precision NaN.  The
> +| `high' and `low' values hold the most- and least-significant bits,
> +| respectively.
> +*----------------------------------------------------------------------------*/
> +#if SNAN_BIT_IS_ONE
> +#define floatx80_default_nan_high 0x7FFF
> +#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
> +#else
> +#define floatx80_default_nan_high 0xFFFF
> +#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
> +#endif
> +
>  #endif
>  
>  #ifdef FLOAT128
> @@ -593,6 +650,18 @@ INLINE int float128_is_any_nan(float128 a)
>          ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
>  }
>  
> +/*----------------------------------------------------------------------------
> +| The pattern for a default generated quadruple-precision NaN.  The `high' and
> +| `low' values hold the most- and least-significant bits, respectively.
> +*----------------------------------------------------------------------------*/
> +#if SNAN_BIT_IS_ONE
> +#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
> +#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
> +#else
> +#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
> +#define float128_default_nan_low  LIT64( 0x0000000000000000 )
> +#endif
> +
>  #endif
>  
>  #else /* CONFIG_SOFTFLOAT */

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>


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

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

* Re: [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512.
  2011-02-18 14:49 ` [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512 Christophe Lyon
@ 2011-02-20 21:52   ` Aurelien Jarno
  2011-02-20 22:09     ` Peter Maydell
  0 siblings, 1 reply; 10+ messages in thread
From: Aurelien Jarno @ 2011-02-20 21:52 UTC (permalink / raw)
  To: Christophe Lyon, g; +Cc: qemu-devel

On Fri, Feb 18, 2011 at 03:49:15PM +0100, Christophe Lyon wrote:
> These constants and utility function are needed to implement some
> helpers. Defining constants avoids the need to re-compute them at
> runtime.
> 
> Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
> ---
>  fpu/softfloat.h |    9 +++++++++
>  1 files changed, 9 insertions(+), 0 deletions(-)
> 
> diff --git a/fpu/softfloat.h b/fpu/softfloat.h
> index f34a938..9bd4a50 100644
> --- a/fpu/softfloat.h
> +++ b/fpu/softfloat.h
> @@ -379,9 +379,15 @@ INLINE int float32_is_zero_or_denormal(float32 a)
>      return (float32_val(a) & 0x7f800000) == 0;
>  }
>  
> +INLINE float32 float32_set_sign(float32 a, int sign)
> +{
> +    return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
> +}
> +
>  #define float32_zero make_float32(0)
>  #define float32_one make_float32(0x3f800000)
>  #define float32_ln2 make_float32(0x3f317218)
> +#define float32_infinity make_float32(0x7f800000)
>  
>  
>  /*----------------------------------------------------------------------------
> @@ -482,6 +488,9 @@ INLINE int float64_is_any_nan(float64 a)
>  #define float64_zero make_float64(0)
>  #define float64_one make_float64(0x3ff0000000000000LL)
>  #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
> +#define float64_half make_float64(0x3fe0000000000000LL)
> +#define float64_256 make_float64(0x4070000000000000LL)
> +#define float64_512 make_float64(0x4080000000000000LL)
>  
>  /*----------------------------------------------------------------------------
>  | The pattern for a default generated double-precision NaN.

While it's probably a good idea to define the commonly used values in
softfloat.h, I don't think we should have all the values used by the
different targets here. Infinity, one, half, two probably have their
place here, I don't think it's the case of 256 and 512. It should be
better to defined them at the target level. Also for consistency, I
think it's better to define these value for all float size, or at least
for all the common ones (32, 64, maybe 16).

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

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

* Re: [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512.
  2011-02-20 21:52   ` Aurelien Jarno
@ 2011-02-20 22:09     ` Peter Maydell
  2011-02-20 22:20       ` Aurelien Jarno
  0 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2011-02-20 22:09 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: Christophe Lyon, qemu-devel, g

On 20 February 2011 21:52, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On Fri, Feb 18, 2011 at 03:49:15PM +0100, Christophe Lyon wrote:

>> +#define float64_half make_float64(0x3fe0000000000000LL)
>> +#define float64_256 make_float64(0x4070000000000000LL)
>> +#define float64_512 make_float64(0x4080000000000000LL)
>>
>>  /*----------------------------------------------------------------------------
>>  | The pattern for a default generated double-precision NaN.
>
> While it's probably a good idea to define the commonly used values in
> softfloat.h, I don't think we should have all the values used by the
> different targets here. Infinity, one, half, two probably have their
> place here, I don't think it's the case of 256 and 512. It should be
> better to defined them at the target level.

Are you happy with targets just doing make_float*() on a
bit pattern? I guess that's the most straightforward thing,
although at the moment the target-arm code seems to prefer
  float32 three = int32_to_float32(3, s);
I don't care very much personally as long as we're not doing
a runtime division to get a constant 0.5 :-)

Incidentally, if you're up for some target-mips cleanup:
target-mips/op_helper.c:#define FLOAT_ONE32 make_float32(0x3f8 << 20)

could be using float32_one instead. (ditto for float64).

> Also for consistency, I
> think it's better to define these value for all float size, or at least
> for all the common ones (32, 64, maybe 16).

I wouldn't bother with 16, only ARM uses that and only for
conversions to other formats.

-- PMM

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

* Re: [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512.
  2011-02-20 22:09     ` Peter Maydell
@ 2011-02-20 22:20       ` Aurelien Jarno
  2011-02-21  9:59         ` Christophe Lyon
  0 siblings, 1 reply; 10+ messages in thread
From: Aurelien Jarno @ 2011-02-20 22:20 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Christophe Lyon, qemu-devel, g

On Sun, Feb 20, 2011 at 10:09:46PM +0000, Peter Maydell wrote:
> On 20 February 2011 21:52, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > On Fri, Feb 18, 2011 at 03:49:15PM +0100, Christophe Lyon wrote:
> 
> >> +#define float64_half make_float64(0x3fe0000000000000LL)
> >> +#define float64_256 make_float64(0x4070000000000000LL)
> >> +#define float64_512 make_float64(0x4080000000000000LL)
> >>
> >>  /*----------------------------------------------------------------------------
> >>  | The pattern for a default generated double-precision NaN.
> >
> > While it's probably a good idea to define the commonly used values in
> > softfloat.h, I don't think we should have all the values used by the
> > different targets here. Infinity, one, half, two probably have their
> > place here, I don't think it's the case of 256 and 512. It should be
> > better to defined them at the target level.
> 
> Are you happy with targets just doing make_float*() on a
> bit pattern? I guess that's the most straightforward thing,

Yes, I think it is the way to go.

> although at the moment the target-arm code seems to prefer
>   float32 three = int32_to_float32(3, s);
> I don't care very much personally as long as we're not doing
> a runtime division to get a constant 0.5 :-)

Doing that at runtime is clearly not a good solution.

> Incidentally, if you're up for some target-mips cleanup:
> target-mips/op_helper.c:#define FLOAT_ONE32 make_float32(0x3f8 << 20)
> 
> could be using float32_one instead. (ditto for float64).

Yes, one is a really common value among target, and in my opinion we
should keep it in softfloat.h. I have a local patch that does this
cleanup and also moves the constant 2 to softfloat.h. I'll submit it one
day with other mips softfloat cleanup.

> > Also for consistency, I
> > think it's better to define these value for all float size, or at least
> > for all the common ones (32, 64, maybe 16).
> 
> I wouldn't bother with 16, only ARM uses that and only for
> conversions to other formats.
> 

That's true, so let's do it float 32 and 64.

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

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

* Re: [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512.
  2011-02-20 22:20       ` Aurelien Jarno
@ 2011-02-21  9:59         ` Christophe Lyon
  0 siblings, 0 replies; 10+ messages in thread
From: Christophe Lyon @ 2011-02-21  9:59 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: Peter Maydell, qemu-devel@nongnu.org, g@hall.aurel32.net

On 20.02.2011 23:20, Aurelien Jarno wrote:
> On Sun, Feb 20, 2011 at 10:09:46PM +0000, Peter Maydell wrote:
>> On 20 February 2011 21:52, Aurelien Jarno <aurelien@aurel32.net> wrote:
>>> While it's probably a good idea to define the commonly used values in
>>> softfloat.h, I don't think we should have all the values used by the
>>> different targets here. Infinity, one, half, two probably have their
>>> place here, I don't think it's the case of 256 and 512. It should be
>>> better to defined them at the target level.
>>
>> Are you happy with targets just doing make_float*() on a
>> bit pattern? I guess that's the most straightforward thing,
> 
> Yes, I think it is the way to go.
> 
OK I will change that.


>>> Also for consistency, I
>>> think it's better to define these value for all float size, or at least
>>> for all the common ones (32, 64, maybe 16).
>>
>> I wouldn't bother with 16, only ARM uses that and only for
>> conversions to other formats.
>>
> 
> That's true, so let's do it float 32 and 64.
> 
I will add these too.

Christophe.

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

end of thread, other threads:[~2011-02-21 10:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-18 14:49 [Qemu-devel] [PATCH v4 0/4] ARM: fix Neon VRECPE and VRSQRTE instructions Christophe Lyon
2011-02-18 14:49 ` [Qemu-devel] [PATCH 1/4] softfloat: move all default NaN definitions to softfloat.h Christophe Lyon
2011-02-20 21:49   ` Aurelien Jarno
2011-02-18 14:49 ` [Qemu-devel] [PATCH 2/4] softfloat: add float32_set_sign(), float32_infinity, float64_half, float64_256 and float64_512 Christophe Lyon
2011-02-20 21:52   ` Aurelien Jarno
2011-02-20 22:09     ` Peter Maydell
2011-02-20 22:20       ` Aurelien Jarno
2011-02-21  9:59         ` Christophe Lyon
2011-02-18 14:49 ` [Qemu-devel] [PATCH 3/4] target-arm: fix support for VRECPE Christophe Lyon
2011-02-18 14:49 ` [Qemu-devel] [PATCH 4/4] target-arm: fix support for VRSQRTE Christophe Lyon

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.