qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 01/19] Add New softfloat Routines for VSX


From: Tom Musta
Subject: [Qemu-devel] [PATCH 01/19] Add New softfloat Routines for VSX
Date: Thu, 24 Oct 2013 11:17:37 -0500
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.0.1

This patch adds routines to the softfloat library that are useful for
the PowerPC VSX implementation.  The routines are, however, not specific
to PowerPC and are approprriate for softfloat.

The following routines are added:

  - float32_is_denormal() returns true if the 32-bit floating point number
    is denormalized.
  - float64_is_denormal() returns true if the 64-bit floating point number
    is denormalized.
  - float32_get_unbiased_exp() returns the unbiased exponent of a 32-bit
    floating point number.
  - float64_get_unbiased_exp() returns the unbiased exponent of a 64-bit
    floating point number.
  - float32_to_uint64() converts a 32-bit floating point number to an
    unsigned 64 bit number.

Note that this patch is dependent a previously submitted patch that fixes
the float64_to_uint64 conversion routine;  see
http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg02622.html
for details.

This contribution can be licensed under either the softfloat-2a or -2b
license.

Signed-off-by: Tom Musta <address@hidden>
---
 fpu/softfloat.c         |   45 +++++++++++++++++++++++++++++++++++++++++++++
 include/fpu/softfloat.h |   22 ++++++++++++++++++++++
 2 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 3070eaa..cb03dca 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1550,6 +1550,51 @@ int64 float32_to_int64( float32 a STATUS_PARAM )

 /*----------------------------------------------------------------------------
 | Returns the result of converting the single-precision floating-point value
+| `a' to the 64-bit unsigned integer format.  The conversion is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic---which means in particular that the conversion is rounded
+| according to the current rounding mode.  If `a' is a NaN, the largest
+| unsigned integer is returned.  Otherwise, if the conversion overflows, the
+| largest unsigned integer is returned.  If the 'a' is negative, zero is
+| returned.
+*----------------------------------------------------------------------------*/
+
+uint64 float32_to_uint64(float32 a STATUS_PARAM)
+{
+    flag aSign;
+    int_fast16_t aExp, shiftCount;
+    uint32_t aSig;
+    uint64_t aSig64, aSigExtra;
+    a = float32_squash_input_denormal(a STATUS_VAR);
+
+    aSig = extractFloat32Frac(a);
+    aExp = extractFloat32Exp(a);
+    aSign = extractFloat32Sign(a);
+    if (aSign) {
+        if (aExp) {
+            float_raise(float_flag_invalid STATUS_VAR);
+        } else if (aSig) { /* negative denormalized */
+            float_raise(float_flag_inexact STATUS_VAR);
+        }
+        return 0;
+    }
+    shiftCount = 0xBE - aExp;
+    if (aExp) {
+        aSig |= 0x00800000;
+    }
+    if (shiftCount < 0) {
+        float_raise(float_flag_invalid STATUS_VAR);
+        return (int64_t)LIT64(0xFFFFFFFFFFFFFFFF);
+    }
+
+    aSig64 = aSig;
+    aSig64 <<= 40;
+    shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
+    return roundAndPackUint64(aSig64, aSigExtra STATUS_VAR);
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the single-precision floating-point value
 | `a' to the 64-bit two's complement integer format.  The conversion is
 | performed according to the IEC/IEEE Standard for Binary Floating-Point
 | Arithmetic, except that the conversion is always rounded toward zero.  If
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index f3927e2..678e527 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -272,6 +272,7 @@ int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM 
);
 uint32 float32_to_uint32( float32 STATUS_PARAM );
 uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
 int64 float32_to_int64( float32 STATUS_PARAM );
+uint64 float32_to_uint64(float32 STATUS_PARAM);
 int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM );
 float64 float32_to_float64( float32 STATUS_PARAM );
 floatx80 float32_to_floatx80( float32 STATUS_PARAM );
@@ -348,6 +349,12 @@ INLINE int float32_is_zero_or_denormal(float32 a)
     return (float32_val(a) & 0x7f800000) == 0;
 }

+INLINE int float32_is_denormal(float32 a)
+{
+    return ((float32_val(a) & 0x7f800000) == 0) &&
+           ((float32_val(a) & 0x007fffff) != 0);
+}
+
 INLINE float32 float32_set_sign(float32 a, int sign)
 {
     return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
@@ -360,6 +367,10 @@ INLINE float32 float32_set_sign(float32 a, int sign)
 #define float32_half make_float32(0x3f000000)
 #define float32_infinity make_float32(0x7f800000)

+INLINE int float32_get_unbiased_exp(float32 f)
+{
+    return ((f >> 23) & 0xFF) - 127;
+}

 /*----------------------------------------------------------------------------
 | The pattern for a default generated single-precision NaN.
@@ -454,6 +465,12 @@ INLINE int float64_is_zero_or_denormal(float64 a)
     return (float64_val(a) & 0x7ff0000000000000LL) == 0;
 }

+INLINE int float64_is_denormal(float64 a)
+{
+    return ((float64_val(a) & 0x7ff0000000000000LL) == 0) &&
+           ((float64_val(a) & 0x000fffffffffffffLL) != 0);
+}
+
 INLINE float64 float64_set_sign(float64 a, int sign)
 {
     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
@@ -472,6 +489,11 @@ INLINE float64 float64_set_sign(float64 a, int sign)
 *----------------------------------------------------------------------------*/
 extern const float64 float64_default_nan;

+INLINE int float64_get_unbiased_exp(float64 f)
+{
+    return ((f >> 52) & 0x7FF) - 1023;
+}
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
 *----------------------------------------------------------------------------*/
--
1.7.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]