diff options
author | Anas Nashif <anas.nashif@intel.com> | 2013-01-15 13:31:42 -0800 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-01-15 13:31:42 -0800 |
commit | 42bf3037d458a330856a0be584200c1e41c3f417 (patch) | |
tree | 25b9be1088727757e52271e25a446e8a852357df /fpu | |
parent | 060629c6ef0b7e5c267d84c91600113264d33120 (diff) | |
download | qemu-42bf3037d458a330856a0be584200c1e41c3f417.tar.gz qemu-42bf3037d458a330856a0be584200c1e41c3f417.tar.bz2 qemu-42bf3037d458a330856a0be584200c1e41c3f417.zip |
Imported Upstream version 1.3.0upstream/1.3.0
Diffstat (limited to 'fpu')
-rw-r--r-- | fpu/softfloat-specialize.h | 99 | ||||
-rw-r--r-- | fpu/softfloat.c | 6 | ||||
-rw-r--r-- | fpu/softfloat.h | 7 |
3 files changed, 106 insertions, 6 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 490245004..518f694a6 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -41,6 +41,13 @@ these four paragraphs for those parts of this code that are retained. #define SNAN_BIT_IS_ONE 0 #endif +#if defined(TARGET_XTENSA) +/* Define for architectures which deviate from IEEE in not supporting + * signaling NaNs (so all NaNs are treated as quiet). + */ +#define NO_SIGNALING_NANS 1 +#endif + /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ @@ -57,7 +64,8 @@ const float16 float16_default_nan = const_float16(0xFE00); *----------------------------------------------------------------------------*/ #if defined(TARGET_SPARC) const float32 float32_default_nan = const_float32(0x7FFFFFFF); -#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) +#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \ + defined(TARGET_XTENSA) const float32 float32_default_nan = const_float32(0x7FC00000); #elif SNAN_BIT_IS_ONE const float32 float32_default_nan = const_float32(0x7FBFFFFF); @@ -127,6 +135,17 @@ typedef struct { uint64_t high, low; } commonNaNT; +#ifdef NO_SIGNALING_NANS +int float16_is_quiet_nan(float16 a_) +{ + return float16_is_any_nan(a_); +} + +int float16_is_signaling_nan(float16 a_) +{ + return 0; +} +#else /*---------------------------------------------------------------------------- | Returns 1 if the half-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -156,6 +175,7 @@ int float16_is_signaling_nan(float16 a_) return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); #endif } +#endif /*---------------------------------------------------------------------------- | Returns a quiet NaN if the half-precision floating point value `a' is a @@ -217,6 +237,17 @@ static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM) } } +#ifdef NO_SIGNALING_NANS +int float32_is_quiet_nan(float32 a_) +{ + return float32_is_any_nan(a_); +} + +int float32_is_signaling_nan(float32 a_) +{ + return 0; +} +#else /*---------------------------------------------------------------------------- | Returns 1 if the single-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -246,6 +277,7 @@ int float32_is_signaling_nan( float32 a_ ) return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); #endif } +#endif /*---------------------------------------------------------------------------- | Returns a quiet NaN if the single-precision floating point value `a' is a @@ -372,7 +404,7 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, return 1; } } -#elif defined(TARGET_PPC) +#elif defined(TARGET_PPC) || defined(TARGET_XTENSA) static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, flag aIsLargerSignificand) { @@ -454,6 +486,33 @@ static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, return 1; } } +#elif defined(TARGET_MIPS) +static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, + flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM) +{ + /* For MIPS, the (inf,zero,qnan) case sets InvalidOp and returns + * the default NaN + */ + if (infzero) { + float_raise(float_flag_invalid STATUS_VAR); + return 3; + } + + /* Prefer sNaN over qNaN, in the a, b, c order. */ + if (aIsSNaN) { + return 0; + } else if (bIsSNaN) { + return 1; + } else if (cIsSNaN) { + return 2; + } else if (aIsQNaN) { + return 0; + } else if (bIsQNaN) { + return 1; + } else { + return 2; + } +} #elif defined(TARGET_PPC) static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM) @@ -586,6 +645,17 @@ static float32 propagateFloat32MulAddNaN(float32 a, float32 b, } } +#ifdef NO_SIGNALING_NANS +int float64_is_quiet_nan(float64 a_) +{ + return float64_is_any_nan(a_); +} + +int float64_is_signaling_nan(float64 a_) +{ + return 0; +} +#else /*---------------------------------------------------------------------------- | Returns 1 if the double-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -619,6 +689,7 @@ int float64_is_signaling_nan( float64 a_ ) && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); #endif } +#endif /*---------------------------------------------------------------------------- | Returns a quiet NaN if the double-precision floating point value `a' is a @@ -773,6 +844,17 @@ static float64 propagateFloat64MulAddNaN(float64 a, float64 b, } } +#ifdef NO_SIGNALING_NANS +int floatx80_is_quiet_nan(floatx80 a_) +{ + return floatx80_is_any_nan(a_); +} + +int floatx80_is_signaling_nan(floatx80 a_) +{ + return 0; +} +#else /*---------------------------------------------------------------------------- | Returns 1 if the extended double-precision floating-point value `a' is a | quiet NaN; otherwise returns 0. This slightly differs from the same @@ -816,6 +898,7 @@ int floatx80_is_signaling_nan( floatx80 a ) && ( a.low == aLow ); #endif } +#endif /*---------------------------------------------------------------------------- | Returns a quiet NaN if the extended double-precision floating point value @@ -929,6 +1012,17 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) } } +#ifdef NO_SIGNALING_NANS +int float128_is_quiet_nan(float128 a_) +{ + return float128_is_any_nan(a_); +} + +int float128_is_signaling_nan(float128 a_) +{ + return 0; +} +#else /*---------------------------------------------------------------------------- | Returns 1 if the quadruple-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -964,6 +1058,7 @@ int float128_is_signaling_nan( float128 a ) && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); #endif } +#endif /*---------------------------------------------------------------------------- | Returns a quiet NaN if the quadruple-precision floating point value `a' is diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b29256a8e..841314686 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1238,7 +1238,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM ) if ( a == 0 ) return float32_zero; shiftCount = countLeadingZeros64( a ) - 40; if ( 0 <= shiftCount ) { - return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount ); + return packFloat32(0, 0x95 - shiftCount, a<<shiftCount); } else { shiftCount += 7; @@ -1248,7 +1248,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM ) else { a <<= shiftCount; } - return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR ); + return roundAndPackFloat32(0, 0x9C - shiftCount, a STATUS_VAR); } } @@ -3007,7 +3007,7 @@ float32 float16_to_float32(float16 a, flag ieee STATUS_PARAM) if (aSig) { return commonNaNToFloat32(float16ToCommonNaN(a STATUS_VAR) STATUS_VAR); } - return packFloat32(aSign, 0xff, aSig << 13); + return packFloat32(aSign, 0xff, 0); } if (aExp == 0) { int8 shiftCount; diff --git a/fpu/softfloat.h b/fpu/softfloat.h index feec3a180..d8999b311 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -219,7 +219,7 @@ void float_raise( int8 flags STATUS_PARAM); enum { float_muladd_negate_c = 1, float_muladd_negate_product = 2, - float_muladd_negate_result = 3, + float_muladd_negate_result = 4, }; /*---------------------------------------------------------------------------- @@ -251,6 +251,11 @@ int float16_is_quiet_nan( float16 ); int float16_is_signaling_nan( float16 ); float16 float16_maybe_silence_nan( float16 ); +INLINE int float16_is_any_nan(float16 a) +{ + return ((float16_val(a) & ~0x8000) > 0x7c00); +} + /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ |