diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-12-25 23:59:51 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-12-25 23:59:51 +0000 |
commit | 85016c983cc25b31b548fd2d146257756b3ac3d9 (patch) | |
tree | 52c85f1a03450824eb09a05d43f73c28293b6325 /fpu | |
parent | e9c71dd1c1f5aeb3732261a02dcfae031973f053 (diff) |
Assortment of soft-float fixes, by Aurelien Jarno.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3860 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'fpu')
-rw-r--r-- | fpu/softfloat-specialize.h | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 18c6dd52d..93fe06ec0 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -65,7 +65,13 @@ typedef struct { /*---------------------------------------------------------------------------- | The pattern for a default generated single-precision NaN. *----------------------------------------------------------------------------*/ -#if SNAN_BIT_IS_ONE +#if defined(TARGET_SPARC) +#define float32_default_nan make_float32(0x7FFFFFFF) +#elif defined(TARGET_POWERPC) +#define float32_default_nan make_float32(0x7FC00000) +#elif defined(TARGET_HPPA) +#define float32_default_nan make_float32(0x7FA00000) +#elif SNAN_BIT_IS_ONE #define float32_default_nan make_float32(0x7FBFFFFF) #else #define float32_default_nan make_float32(0xFFC00000) @@ -125,8 +131,12 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) static float32 commonNaNToFloat32( commonNaNT a ) { - return make_float32( - ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ) ); + bits32 mantissa = a.high>>41; + if ( mantissa ) + return make_float32( + ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) ); + else + return float32_default_nan; } /*---------------------------------------------------------------------------- @@ -180,7 +190,13 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) /*---------------------------------------------------------------------------- | The pattern for a default generated double-precision NaN. *----------------------------------------------------------------------------*/ -#if SNAN_BIT_IS_ONE +#if defined(TARGET_SPARC) +#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF )) +#elif defined(TARGET_POWERPC) +#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 )) +#elif defined(TARGET_HPPA) +#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 )) +#elif SNAN_BIT_IS_ONE #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF )) #else #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 )) @@ -244,10 +260,15 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) static float64 commonNaNToFloat64( commonNaNT a ) { - return make_float64( - ( ( (bits64) a.sign )<<63 ) - | LIT64( 0x7FF8000000000000 ) - | ( a.high>>12 )); + bits64 mantissa = a.high>>12; + + if ( mantissa ) + return make_float64( + ( ( (bits64) a.sign )<<63 ) + | LIT64( 0x7FF0000000000000 ) + | ( a.high>>12 )); + else + return float64_default_nan; } /*---------------------------------------------------------------------------- @@ -366,7 +387,7 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) 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<<1; + z.high = a.low; return z; } @@ -379,7 +400,10 @@ static floatx80 commonNaNToFloatx80( commonNaNT a ) { floatx80 z; - z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); + if (a.high) + z.low = a.high; + else + z.low = floatx80_default_nan_low; z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; return z; } @@ -500,7 +524,7 @@ static float128 commonNaNToFloat128( commonNaNT a ) float128 z; shift128Right( a.high, a.low, 16, &z.high, &z.low ); - z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); + z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); return z; } |