On Mon, 2007-03-19 at 22:53 +0000, Julian Seward wrote:
> Thinking about this more, you ask "is this correct", but that
> is only meaningful if you say what the specification is.  
> Correct relative to what?
> 
> > Yes, it seems to be the correct way, but thinking more about the
> > problem, it appeared to me that the implementation could be even easier
> > than yours. It seems to me that this may be sufficient:
> > uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
> > {
> >     int64_t v;
> >
> >     v = llrint(a + (float64)INT64_MIN);
> >
> >     return v - INT64_MIN;
> > }
> 
> If a is NaN then so is the argument to llrint.  'man llrint' says:
> 
>   If x is infinite or NaN, or if the rounded value is
>   outside  the  range  of  the  return type, the numeric result
>   is unspecified. 
> 
> So then float64_to_uint64 produces an unspecified result.
> 
> It seems to me much safer to test and handle NaN, Inf and
> out-of-range values specially.  However, even that does not help
> unless you say what the specification is.

Well, you are right, but the function float64_to_int64 acts the same way
in that code.
If we want to follow IEEE compliance, we have to use the softfloat
functions instead, not the softfloat-native ones. Or we should sanitize
the whole softfloat.c code, to be consistent, it seems.

Here's an updated patch, with two more functions. The added functions
are:
float32 uint32_to_float32(unsigned int v STATUS_PARAM)
float64 uint32_to_float64(unsigned int v STATUS_PARAM)
float32 uint64_to_float32( uint64_t v STATUS_PARAM)
float64 uint64_to_float64( uint64_t v STATUS_PARAM)
unsigned int float32_to_uint32( float32 a STATUS_PARAM)
unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
unsigned int float64_to_uint32( float64 a STATUS_PARAM)
unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)

Note that some of those functions already exist in softfloat.c but not
in softfloat-native.c.

-- 
J. Mayer <[EMAIL PROTECTED]>
Never organized
Index: fpu/softfloat-native.c
===================================================================
RCS file: /sources/qemu/qemu/fpu/softfloat-native.c,v
retrieving revision 1.6
diff -u -d -d -p -r1.6 softfloat-native.c
--- fpu/softfloat-native.c	28 Oct 2006 19:27:11 -0000	1.6
+++ fpu/softfloat-native.c	19 Mar 2007 23:05:29 -0000
@@ -59,11 +59,21 @@ float32 int32_to_float32(int v STATUS_PA
     return (float32)v;
 }
 
+float32 uint32_to_float32(unsigned int v STATUS_PARAM)
+{
+    return (float32)v;
+}
+
 float64 int32_to_float64(int v STATUS_PARAM)
 {
     return (float64)v;
 }
 
+float64 uint32_to_float64(unsigned int v STATUS_PARAM)
+{
+    return (float64)v;
+}
+
 #ifdef FLOATX80
 floatx80 int32_to_floatx80(int v STATUS_PARAM)
 {
@@ -74,10 +84,18 @@ float32 int64_to_float32( int64_t v STAT
 {
     return (float32)v;
 }
+float32 uint64_to_float32( uint64_t v STATUS_PARAM)
+{
+    return (float32)v;
+}
 float64 int64_to_float64( int64_t v STATUS_PARAM)
 {
     return (float64)v;
 }
+float64 uint64_to_float64( uint64_t v STATUS_PARAM)
+{
+    return (float64)v;
+}
 #ifdef FLOATX80
 floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
 {
@@ -132,6 +150,37 @@ floatx80 float32_to_floatx80( float32 a 
 }
 #endif
 
+unsigned int float32_to_uint32( float32 a STATUS_PARAM)
+{
+    int64_t v;
+    unsigned int res;
+
+    v = llrintf(a);
+    if (v < 0) {
+        res = 0;
+    } else if (v > 0xffffffff) {
+        res = 0xffffffff;
+    } else {
+        res = v;
+    }
+    return res;
+}
+unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
+{
+    int64_t v;
+    unsigned int res;
+
+    v = (int64_t)a;
+    if (v < 0) {
+        res = 0;
+    } else if (v > 0xffffffff) {
+        res = 0xffffffff;
+    } else {
+        res = v;
+    }
+    return res;
+}
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE single-precision operations.
 *----------------------------------------------------------------------------*/
@@ -218,6 +267,53 @@ float128 float64_to_float128( float64 a 
 }
 #endif
 
+unsigned int float64_to_uint32( float64 a STATUS_PARAM)
+{
+    int64_t v;
+    unsigned int res;
+
+    v = llrint(a);
+    if (v < 0) {
+        res = 0;
+    } else if (v > 0xffffffff) {
+        res = 0xffffffff;
+    } else {
+        res = v;
+    }
+    return res;
+}
+unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
+{
+    int64_t v;
+    unsigned int res;
+
+    v = (int64_t)a;
+    if (v < 0) {
+        res = 0;
+    } else if (v > 0xffffffff) {
+        res = 0xffffffff;
+    } else {
+        res = v;
+    }
+    return res;
+}
+uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
+{
+    int64_t v;
+
+    v = llrint(a + (float64)INT64_MIN);
+
+    return v - INT64_MIN;
+}
+uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
+{
+    int64_t v;
+
+    v = (int64_t)(a + (float64)INT64_MIN);
+
+    return v - INT64_MIN;
+}
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE double-precision operations.
 *----------------------------------------------------------------------------*/
Index: fpu/softfloat-native.h
===================================================================
RCS file: /sources/qemu/qemu/fpu/softfloat-native.h,v
retrieving revision 1.8
diff -u -d -d -p -r1.8 softfloat-native.h
--- fpu/softfloat-native.h	28 Oct 2006 19:27:11 -0000	1.8
+++ fpu/softfloat-native.h	19 Mar 2007 23:05:29 -0000
@@ -99,7 +99,9 @@ void set_floatx80_rounding_precision(int
 | Software IEC/IEEE integer-to-floating-point conversion routines.
 *----------------------------------------------------------------------------*/
 float32 int32_to_float32( int STATUS_PARAM);
+float32 uint32_to_float32( unsigned int STATUS_PARAM);
 float64 int32_to_float64( int STATUS_PARAM);
+float64 uint32_to_float64( unsigned int STATUS_PARAM);
 #ifdef FLOATX80
 floatx80 int32_to_floatx80( int STATUS_PARAM);
 #endif
@@ -107,7 +109,9 @@ floatx80 int32_to_floatx80( int STATUS_P
 float128 int32_to_float128( int STATUS_PARAM);
 #endif
 float32 int64_to_float32( int64_t STATUS_PARAM);
+float32 uint64_to_float32( uint64_t STATUS_PARAM);
 float64 int64_to_float64( int64_t STATUS_PARAM);
+float64 uint64_to_float64( uint64_t v STATUS_PARAM);
 #ifdef FLOATX80
 floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
 #endif
@@ -120,6 +124,8 @@ float128 int64_to_float128( int64_t STAT
 *----------------------------------------------------------------------------*/
 int float32_to_int32( float32  STATUS_PARAM);
 int float32_to_int32_round_to_zero( float32  STATUS_PARAM);
+unsigned int float32_to_uint32( float32 a STATUS_PARAM);
+unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM);
 int64_t float32_to_int64( float32  STATUS_PARAM);
 int64_t float32_to_int64_round_to_zero( float32  STATUS_PARAM);
 float64 float32_to_float64( float32  STATUS_PARAM);
@@ -200,8 +206,12 @@ INLINE float32 float32_chs(float32 a)
 *----------------------------------------------------------------------------*/
 int float64_to_int32( float64 STATUS_PARAM );
 int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
+unsigned int float64_to_uint32( float64 STATUS_PARAM );
+unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
 int64_t float64_to_int64( float64 STATUS_PARAM );
 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
+uint64_t float64_to_uint64( float64 STATUS_PARAM );
+uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM );
 float32 float64_to_float32( float64 STATUS_PARAM );
 #ifdef FLOATX80
 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
Index: fpu/softfloat.c
===================================================================
RCS file: /sources/qemu/qemu/fpu/softfloat.c,v
retrieving revision 1.4
diff -u -d -d -p -r1.4 softfloat.c
--- fpu/softfloat.c	28 Oct 2006 19:27:11 -0000	1.4
+++ fpu/softfloat.c	19 Mar 2007 23:05:29 -0000
@@ -1164,6 +1164,27 @@ float32 int64_to_float32( int64 a STATUS
 
 }
 
+float64 uint64_to_float32( uint64 a STATUS_PARAM )
+{
+    int8 shiftCount;
+
+    if ( a == 0 ) return 0;
+    shiftCount = countLeadingZeros64( a ) - 40;
+    if ( 0 <= shiftCount ) {
+        return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount );
+    }
+    else {
+        shiftCount += 7;
+        if ( shiftCount < 0 ) {
+            shift64RightJamming( a, - shiftCount, &a );
+        }
+        else {
+            a <<= shiftCount;
+        }
+        return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR );
+    }
+}
+
 /*----------------------------------------------------------------------------
 | Returns the result of converting the 64-bit two's complement integer `a'
 | to the double-precision floating-point format.  The conversion is performed
@@ -1183,6 +1204,13 @@ float64 int64_to_float64( int64 a STATUS
 
 }
 
+float64 uint64_to_float64( uint64 a STATUS_PARAM )
+{
+    if ( a == 0 ) return 0;
+    return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR );
+
+}
+
 #ifdef FLOATX80
 
 /*----------------------------------------------------------------------------
@@ -5282,6 +5310,26 @@ unsigned int float64_to_uint32_round_to_
     return res;
 }
 
+uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
+{
+    int64_t v;
+
+    v = int64_to_float64(INT64_MIN STATUS_VAR);
+    v = float64_to_int64((a + v) STATUS_VAR);
+
+    return v - INT64_MIN;
+}
+
+uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
+{
+    int64_t v;
+
+    v = int64_to_float64(INT64_MIN STATUS_VAR);
+    v = float64_to_int64_round_to_zero((a + v) STATUS_VAR);
+
+    return v - INT64_MIN;
+}
+
 #define COMPARE(s, nan_exp)                                                  \
 INLINE int float ## s ## _compare_internal( float ## s a, float ## s b,      \
                                       int is_quiet STATUS_PARAM )            \
Index: fpu/softfloat.h
===================================================================
RCS file: /sources/qemu/qemu/fpu/softfloat.h,v
retrieving revision 1.5
diff -u -d -d -p -r1.5 softfloat.h
--- fpu/softfloat.h	28 Oct 2006 19:27:11 -0000	1.5
+++ fpu/softfloat.h	19 Mar 2007 23:05:29 -0000
@@ -193,7 +193,9 @@ floatx80 int32_to_floatx80( int STATUS_P
 float128 int32_to_float128( int STATUS_PARAM );
 #endif
 float32 int64_to_float32( int64_t STATUS_PARAM );
+float32 uint64_to_float32( uint64_t STATUS_PARAM );
 float64 int64_to_float64( int64_t STATUS_PARAM );
+float64 uint64_to_float64( uint64_t STATUS_PARAM );
 #ifdef FLOATX80
 floatx80 int64_to_floatx80( int64_t STATUS_PARAM );
 #endif
@@ -258,6 +260,8 @@ unsigned int float64_to_uint32( float64 
 unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
 int64_t float64_to_int64( float64 STATUS_PARAM );
 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
+uint64_t float64_to_uint64 (float64 a STATUS_PARAM);
+uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
 float32 float64_to_float32( float64 STATUS_PARAM );
 #ifdef FLOATX80
 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to