diff options
Diffstat (limited to 'fpu/softfloat-specialize.h')
-rw-r--r-- | fpu/softfloat-specialize.h | 549 |
1 files changed, 264 insertions, 285 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index a4cbdad452..39095e542f 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -79,16 +79,6 @@ this code that are retained. * version 2 or later. See the COPYING file in the top-level directory. */ -/* Does the target distinguish signaling NaNs from non-signaling NaNs - * by setting the most significant bit of the mantissa for a signaling NaN? - * (The more common choice is to have it be zero for SNaN and one for QNaN.) - */ -#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) -#define SNAN_BIT_IS_ONE 1 -#else -#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). @@ -99,73 +89,94 @@ this code that are retained. /*---------------------------------------------------------------------------- | The pattern for a default generated half-precision NaN. *----------------------------------------------------------------------------*/ +float16 float16_default_nan(float_status *status) +{ #if defined(TARGET_ARM) -const float16 float16_default_nan = const_float16(0x7E00); -#elif SNAN_BIT_IS_ONE -const float16 float16_default_nan = const_float16(0x7DFF); + return const_float16(0x7E00); #else -const float16 float16_default_nan = const_float16(0xFE00); + if (status->snan_bit_is_one) { + return const_float16(0x7DFF); + } else { + return const_float16(0xFE00); + } #endif +} /*---------------------------------------------------------------------------- | The pattern for a default generated single-precision NaN. *----------------------------------------------------------------------------*/ +float32 float32_default_nan(float_status *status) +{ #if defined(TARGET_SPARC) -const float32 float32_default_nan = const_float32(0x7FFFFFFF); + return const_float32(0x7FFFFFFF); #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \ defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE) -const float32 float32_default_nan = const_float32(0x7FC00000); -#elif SNAN_BIT_IS_ONE -const float32 float32_default_nan = const_float32(0x7FBFFFFF); + return const_float32(0x7FC00000); #else -const float32 float32_default_nan = const_float32(0xFFC00000); + if (status->snan_bit_is_one) { + return const_float32(0x7FBFFFFF); + } else { + return const_float32(0xFFC00000); + } #endif +} /*---------------------------------------------------------------------------- | The pattern for a default generated double-precision NaN. *----------------------------------------------------------------------------*/ +float64 float64_default_nan(float_status *status) +{ #if defined(TARGET_SPARC) -const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF )); + return const_float64(LIT64(0x7FFFFFFFFFFFFFFF)); #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \ defined(TARGET_S390X) -const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 )); -#elif SNAN_BIT_IS_ONE -const float64 float64_default_nan = const_float64(LIT64(0x7FF7FFFFFFFFFFFF)); + return const_float64(LIT64(0x7FF8000000000000)); #else -const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 )); + if (status->snan_bit_is_one) { + return const_float64(LIT64(0x7FF7FFFFFFFFFFFF)); + } else { + return const_float64(LIT64(0xFFF8000000000000)); + } #endif +} /*---------------------------------------------------------------------------- | The pattern for a default generated extended double-precision NaN. *----------------------------------------------------------------------------*/ -#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 +floatx80 floatx80_default_nan(float_status *status) +{ + floatx80 r; -const floatx80 floatx80_default_nan - = make_floatx80_init(floatx80_default_nan_high, floatx80_default_nan_low); + if (status->snan_bit_is_one) { + r.low = LIT64(0xBFFFFFFFFFFFFFFF); + r.high = 0x7FFF; + } else { + r.low = LIT64(0xC000000000000000); + r.high = 0xFFFF; + } + return r; +} /*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. The `high' and -| `low' values hold the most- and least-significant bits, respectively. +| The pattern for a default generated quadruple-precision NaN. *----------------------------------------------------------------------------*/ -#if SNAN_BIT_IS_ONE -#define float128_default_nan_high LIT64(0x7FFF7FFFFFFFFFFF) -#define float128_default_nan_low LIT64(0xFFFFFFFFFFFFFFFF) -#elif defined(TARGET_S390X) -#define float128_default_nan_high LIT64( 0x7FFF800000000000 ) -#define float128_default_nan_low LIT64( 0x0000000000000000 ) +float128 float128_default_nan(float_status *status) +{ + float128 r; + + if (status->snan_bit_is_one) { + r.low = LIT64(0xFFFFFFFFFFFFFFFF); + r.high = LIT64(0x7FFF7FFFFFFFFFFF); + } else { + r.low = LIT64(0x0000000000000000); +#if defined(TARGET_S390X) + r.high = LIT64(0x7FFF800000000000); #else -#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) -#define float128_default_nan_low LIT64( 0x0000000000000000 ) + r.high = LIT64(0xFFFF800000000000); #endif - -const float128 float128_default_nan - = make_float128_init(float128_default_nan_high, float128_default_nan_low); + } + return r; +} /*---------------------------------------------------------------------------- | Raises the exceptions specified by `flags'. Floating-point traps can be @@ -188,12 +199,12 @@ typedef struct { } commonNaNT; #ifdef NO_SIGNALING_NANS -int float16_is_quiet_nan(float16 a_) +int float16_is_quiet_nan(float16 a_, float_status *status) { return float16_is_any_nan(a_); } -int float16_is_signaling_nan(float16 a_) +int float16_is_signaling_nan(float16 a_, float_status *status) { return 0; } @@ -203,14 +214,14 @@ int float16_is_signaling_nan(float16 a_) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float16_is_quiet_nan(float16 a_) +int float16_is_quiet_nan(float16 a_, float_status *status) { uint16_t a = float16_val(a_); -#if SNAN_BIT_IS_ONE - return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); -#else - return ((a & ~0x8000) >= 0x7c80); -#endif + if (status->snan_bit_is_one) { + return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); + } else { + return ((a & ~0x8000) >= 0x7C80); + } } /*---------------------------------------------------------------------------- @@ -218,14 +229,14 @@ int float16_is_quiet_nan(float16 a_) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float16_is_signaling_nan(float16 a_) +int float16_is_signaling_nan(float16 a_, float_status *status) { uint16_t a = float16_val(a_); -#if SNAN_BIT_IS_ONE - return ((a & ~0x8000) >= 0x7c80); -#else - return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); -#endif + if (status->snan_bit_is_one) { + return ((a & ~0x8000) >= 0x7C80); + } else { + return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); + } } #endif @@ -233,20 +244,16 @@ int float16_is_signaling_nan(float16 a_) | Returns a quiet NaN if the half-precision floating point value `a' is a | signaling NaN; otherwise returns `a'. *----------------------------------------------------------------------------*/ -float16 float16_maybe_silence_nan(float16 a_) +float16 float16_maybe_silence_nan(float16 a_, float_status *status) { - if (float16_is_signaling_nan(a_)) { -#if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) - return float16_default_nan; -# else -# error Rules for silencing a signaling NaN are target-specific -# endif -#else - uint16_t a = float16_val(a_); - a |= (1 << 9); - return make_float16(a); -#endif + if (float16_is_signaling_nan(a_, status)) { + if (status->snan_bit_is_one) { + return float16_default_nan(status); + } else { + uint16_t a = float16_val(a_); + a |= (1 << 9); + return make_float16(a); + } } return a_; } @@ -261,7 +268,7 @@ static commonNaNT float16ToCommonNaN(float16 a, float_status *status) { commonNaNT z; - if (float16_is_signaling_nan(a)) { + if (float16_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } z.sign = float16_val(a) >> 15; @@ -280,24 +287,24 @@ static float16 commonNaNToFloat16(commonNaNT a, float_status *status) uint16_t mantissa = a.high>>54; if (status->default_nan_mode) { - return float16_default_nan; + return float16_default_nan(status); } if (mantissa) { return make_float16(((((uint16_t) a.sign) << 15) | (0x1F << 10) | mantissa)); } else { - return float16_default_nan; + return float16_default_nan(status); } } #ifdef NO_SIGNALING_NANS -int float32_is_quiet_nan(float32 a_) +int float32_is_quiet_nan(float32 a_, float_status *status) { return float32_is_any_nan(a_); } -int float32_is_signaling_nan(float32 a_) +int float32_is_signaling_nan(float32 a_, float_status *status) { return 0; } @@ -307,14 +314,14 @@ int float32_is_signaling_nan(float32 a_) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float32_is_quiet_nan( float32 a_ ) +int float32_is_quiet_nan(float32 a_, float_status *status) { uint32_t a = float32_val(a_); -#if SNAN_BIT_IS_ONE - return (((a >> 22) & 0x1ff) == 0x1fe) && (a & 0x003fffff); -#else - return ((uint32_t)(a << 1) >= 0xff800000); -#endif + if (status->snan_bit_is_one) { + return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); + } else { + return ((uint32_t)(a << 1) >= 0xFF800000); + } } /*---------------------------------------------------------------------------- @@ -322,14 +329,14 @@ int float32_is_quiet_nan( float32 a_ ) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float32_is_signaling_nan( float32 a_ ) +int float32_is_signaling_nan(float32 a_, float_status *status) { uint32_t a = float32_val(a_); -#if SNAN_BIT_IS_ONE - return ((uint32_t)(a << 1) >= 0xff800000); -#else - return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); -#endif + if (status->snan_bit_is_one) { + return ((uint32_t)(a << 1) >= 0xFF800000); + } else { + return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); + } } #endif @@ -338,20 +345,16 @@ int float32_is_signaling_nan( float32 a_ ) | signaling NaN; otherwise returns `a'. *----------------------------------------------------------------------------*/ -float32 float32_maybe_silence_nan( float32 a_ ) +float32 float32_maybe_silence_nan(float32 a_, float_status *status) { - if (float32_is_signaling_nan(a_)) { -#if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) - return float32_default_nan; -# else -# error Rules for silencing a signaling NaN are target-specific -# endif -#else - uint32_t a = float32_val(a_); - a |= (1 << 22); - return make_float32(a); -#endif + if (float32_is_signaling_nan(a_, status)) { + if (status->snan_bit_is_one) { + return float32_default_nan(status); + } else { + uint32_t a = float32_val(a_); + a |= (1 << 22); + return make_float32(a); + } } return a_; } @@ -366,7 +369,7 @@ static commonNaNT float32ToCommonNaN(float32 a, float_status *status) { commonNaNT z; - if (float32_is_signaling_nan(a)) { + if (float32_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } z.sign = float32_val(a)>>31; @@ -385,14 +388,15 @@ static float32 commonNaNToFloat32(commonNaNT a, float_status *status) uint32_t mantissa = a.high>>41; if (status->default_nan_mode) { - return float32_default_nan; + return float32_default_nan(status); } - if ( mantissa ) + if (mantissa) { return make_float32( ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) ); - else - return float32_default_nan; + } else { + return float32_default_nan(status); + } } /*---------------------------------------------------------------------------- @@ -626,10 +630,10 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) flag aIsLargerSignificand; uint32_t av, bv; - aIsQuietNaN = float32_is_quiet_nan( a ); - aIsSignalingNaN = float32_is_signaling_nan( a ); - bIsQuietNaN = float32_is_quiet_nan( b ); - bIsSignalingNaN = float32_is_signaling_nan( b ); + aIsQuietNaN = float32_is_quiet_nan(a, status); + aIsSignalingNaN = float32_is_signaling_nan(a, status); + bIsQuietNaN = float32_is_quiet_nan(b, status); + bIsSignalingNaN = float32_is_signaling_nan(b, status); av = float32_val(a); bv = float32_val(b); @@ -637,8 +641,9 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) float_raise(float_flag_invalid, status); } - if (status->default_nan_mode) - return float32_default_nan; + if (status->default_nan_mode) { + return float32_default_nan(status); + } if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) { aIsLargerSignificand = 0; @@ -650,9 +655,9 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, aIsLargerSignificand)) { - return float32_maybe_silence_nan(b); + return float32_maybe_silence_nan(b, status); } else { - return float32_maybe_silence_nan(a); + return float32_maybe_silence_nan(a, status); } } @@ -673,12 +678,12 @@ static float32 propagateFloat32MulAddNaN(float32 a, float32 b, cIsQuietNaN, cIsSignalingNaN; int which; - aIsQuietNaN = float32_is_quiet_nan(a); - aIsSignalingNaN = float32_is_signaling_nan(a); - bIsQuietNaN = float32_is_quiet_nan(b); - bIsSignalingNaN = float32_is_signaling_nan(b); - cIsQuietNaN = float32_is_quiet_nan(c); - cIsSignalingNaN = float32_is_signaling_nan(c); + aIsQuietNaN = float32_is_quiet_nan(a, status); + aIsSignalingNaN = float32_is_signaling_nan(a, status); + bIsQuietNaN = float32_is_quiet_nan(b, status); + bIsSignalingNaN = float32_is_signaling_nan(b, status); + cIsQuietNaN = float32_is_quiet_nan(c, status); + cIsSignalingNaN = float32_is_signaling_nan(c, status); if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { float_raise(float_flag_invalid, status); @@ -692,29 +697,29 @@ static float32 propagateFloat32MulAddNaN(float32 a, float32 b, /* Note that this check is after pickNaNMulAdd so that function * has an opportunity to set the Invalid flag. */ - return float32_default_nan; + return float32_default_nan(status); } switch (which) { case 0: - return float32_maybe_silence_nan(a); + return float32_maybe_silence_nan(a, status); case 1: - return float32_maybe_silence_nan(b); + return float32_maybe_silence_nan(b, status); case 2: - return float32_maybe_silence_nan(c); + return float32_maybe_silence_nan(c, status); case 3: default: - return float32_default_nan; + return float32_default_nan(status); } } #ifdef NO_SIGNALING_NANS -int float64_is_quiet_nan(float64 a_) +int float64_is_quiet_nan(float64 a_, float_status *status) { return float64_is_any_nan(a_); } -int float64_is_signaling_nan(float64 a_) +int float64_is_signaling_nan(float64 a_, float_status *status) { return 0; } @@ -724,15 +729,15 @@ int float64_is_signaling_nan(float64 a_) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float64_is_quiet_nan( float64 a_ ) +int float64_is_quiet_nan(float64 a_, float_status *status) { uint64_t a = float64_val(a_); -#if SNAN_BIT_IS_ONE - return (((a >> 51) & 0xfff) == 0xffe) - && (a & 0x0007ffffffffffffULL); -#else - return ((a << 1) >= 0xfff0000000000000ULL); -#endif + if (status->snan_bit_is_one) { + return (((a >> 51) & 0xFFF) == 0xFFE) + && (a & 0x0007FFFFFFFFFFFFULL); + } else { + return ((a << 1) >= 0xFFF0000000000000ULL); + } } /*---------------------------------------------------------------------------- @@ -740,16 +745,15 @@ int float64_is_quiet_nan( float64 a_ ) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float64_is_signaling_nan( float64 a_ ) +int float64_is_signaling_nan(float64 a_, float_status *status) { uint64_t a = float64_val(a_); -#if SNAN_BIT_IS_ONE - return ((a << 1) >= 0xfff0000000000000ULL); -#else - return - ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) - && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); -#endif + if (status->snan_bit_is_one) { + return ((a << 1) >= 0xFFF0000000000000ULL); + } else { + return (((a >> 51) & 0xFFF) == 0xFFE) + && (a & LIT64(0x0007FFFFFFFFFFFF)); + } } #endif @@ -758,20 +762,16 @@ int float64_is_signaling_nan( float64 a_ ) | signaling NaN; otherwise returns `a'. *----------------------------------------------------------------------------*/ -float64 float64_maybe_silence_nan( float64 a_ ) +float64 float64_maybe_silence_nan(float64 a_, float_status *status) { - if (float64_is_signaling_nan(a_)) { -#if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) - return float64_default_nan; -# else -# error Rules for silencing a signaling NaN are target-specific -# endif -#else - uint64_t a = float64_val(a_); - a |= LIT64( 0x0008000000000000 ); - return make_float64(a); -#endif + if (float64_is_signaling_nan(a_, status)) { + if (status->snan_bit_is_one) { + return float64_default_nan(status); + } else { + uint64_t a = float64_val(a_); + a |= LIT64(0x0008000000000000); + return make_float64(a); + } } return a_; } @@ -786,7 +786,7 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status) { commonNaNT z; - if (float64_is_signaling_nan(a)) { + if (float64_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } z.sign = float64_val(a)>>63; @@ -805,16 +805,17 @@ static float64 commonNaNToFloat64(commonNaNT a, float_status *status) uint64_t mantissa = a.high>>12; if (status->default_nan_mode) { - return float64_default_nan; + return float64_default_nan(status); } - if ( mantissa ) + if (mantissa) { return make_float64( ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FF0000000000000 ) | ( a.high>>12 )); - else - return float64_default_nan; + } else { + return float64_default_nan(status); + } } /*---------------------------------------------------------------------------- @@ -829,10 +830,10 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) flag aIsLargerSignificand; uint64_t av, bv; - aIsQuietNaN = float64_is_quiet_nan( a ); - aIsSignalingNaN = float64_is_signaling_nan( a ); - bIsQuietNaN = float64_is_quiet_nan( b ); - bIsSignalingNaN = float64_is_signaling_nan( b ); + aIsQuietNaN = float64_is_quiet_nan(a, status); + aIsSignalingNaN = float64_is_signaling_nan(a, status); + bIsQuietNaN = float64_is_quiet_nan(b, status); + bIsSignalingNaN = float64_is_signaling_nan(b, status); av = float64_val(a); bv = float64_val(b); @@ -840,8 +841,9 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) float_raise(float_flag_invalid, status); } - if (status->default_nan_mode) - return float64_default_nan; + if (status->default_nan_mode) { + return float64_default_nan(status); + } if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) { aIsLargerSignificand = 0; @@ -853,9 +855,9 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, aIsLargerSignificand)) { - return float64_maybe_silence_nan(b); + return float64_maybe_silence_nan(b, status); } else { - return float64_maybe_silence_nan(a); + return float64_maybe_silence_nan(a, status); } } @@ -876,12 +878,12 @@ static float64 propagateFloat64MulAddNaN(float64 a, float64 b, cIsQuietNaN, cIsSignalingNaN; int which; - aIsQuietNaN = float64_is_quiet_nan(a); - aIsSignalingNaN = float64_is_signaling_nan(a); - bIsQuietNaN = float64_is_quiet_nan(b); - bIsSignalingNaN = float64_is_signaling_nan(b); - cIsQuietNaN = float64_is_quiet_nan(c); - cIsSignalingNaN = float64_is_signaling_nan(c); + aIsQuietNaN = float64_is_quiet_nan(a, status); + aIsSignalingNaN = float64_is_signaling_nan(a, status); + bIsQuietNaN = float64_is_quiet_nan(b, status); + bIsSignalingNaN = float64_is_signaling_nan(b, status); + cIsQuietNaN = float64_is_quiet_nan(c, status); + cIsSignalingNaN = float64_is_signaling_nan(c, status); if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { float_raise(float_flag_invalid, status); @@ -895,29 +897,29 @@ static float64 propagateFloat64MulAddNaN(float64 a, float64 b, /* Note that this check is after pickNaNMulAdd so that function * has an opportunity to set the Invalid flag. */ - return float64_default_nan; + return float64_default_nan(status); } switch (which) { case 0: - return float64_maybe_silence_nan(a); + return float64_maybe_silence_nan(a, status); case 1: - return float64_maybe_silence_nan(b); + return float64_maybe_silence_nan(b, status); case 2: - return float64_maybe_silence_nan(c); + return float64_maybe_silence_nan(c, status); case 3: default: - return float64_default_nan; + return float64_default_nan(status); } } #ifdef NO_SIGNALING_NANS -int floatx80_is_quiet_nan(floatx80 a_) +int floatx80_is_quiet_nan(floatx80 a_, float_status *status) { return floatx80_is_any_nan(a_); } -int floatx80_is_signaling_nan(floatx80 a_) +int floatx80_is_signaling_nan(floatx80 a_, float_status *status) { return 0; } @@ -928,19 +930,19 @@ int floatx80_is_signaling_nan(floatx80 a_) | function for other types as floatx80 has an explicit bit. *----------------------------------------------------------------------------*/ -int floatx80_is_quiet_nan( floatx80 a ) +int floatx80_is_quiet_nan(floatx80 a, float_status *status) { -#if SNAN_BIT_IS_ONE - uint64_t aLow; + if (status->snan_bit_is_one) { + uint64_t aLow; - aLow = a.low & ~0x4000000000000000ULL; - return ((a.high & 0x7fff) == 0x7fff) - && (aLow << 1) - && (a.low == aLow); -#else - return ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 ))); -#endif + aLow = a.low & ~0x4000000000000000ULL; + return ((a.high & 0x7FFF) == 0x7FFF) + && (aLow << 1) + && (a.low == aLow); + } else { + return ((a.high & 0x7FFF) == 0x7FFF) + && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1))); + } } /*---------------------------------------------------------------------------- @@ -949,20 +951,19 @@ int floatx80_is_quiet_nan( floatx80 a ) | function for other types as floatx80 has an explicit bit. *----------------------------------------------------------------------------*/ -int floatx80_is_signaling_nan( floatx80 a ) +int floatx80_is_signaling_nan(floatx80 a, float_status *status) { -#if SNAN_BIT_IS_ONE - return ((a.high & 0x7fff) == 0x7fff) - && ((a.low << 1) >= 0x8000000000000000ULL); -#else - uint64_t aLow; + if (status->snan_bit_is_one) { + return ((a.high & 0x7FFF) == 0x7FFF) + && ((a.low << 1) >= 0x8000000000000000ULL); + } else { + uint64_t aLow; - aLow = a.low & ~ LIT64( 0x4000000000000000 ); - return - ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (uint64_t) ( aLow<<1 ) - && ( a.low == aLow ); -#endif + aLow = a.low & ~LIT64(0x4000000000000000); + return ((a.high & 0x7FFF) == 0x7FFF) + && (uint64_t)(aLow << 1) + && (a.low == aLow); + } } #endif @@ -971,20 +972,15 @@ int floatx80_is_signaling_nan( floatx80 a ) | `a' is a signaling NaN; otherwise returns `a'. *----------------------------------------------------------------------------*/ -floatx80 floatx80_maybe_silence_nan( floatx80 a ) +floatx80 floatx80_maybe_silence_nan(floatx80 a, float_status *status) { - if (floatx80_is_signaling_nan(a)) { -#if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; -# else -# error Rules for silencing a signaling NaN are target-specific -# endif -#else - a.low |= LIT64( 0xC000000000000000 ); - return a; -#endif + if (floatx80_is_signaling_nan(a, status)) { + if (status->snan_bit_is_one) { + a = floatx80_default_nan(status); + } else { + a.low |= LIT64(0xC000000000000000); + return a; + } } return a; } @@ -997,9 +993,10 @@ floatx80 floatx80_maybe_silence_nan( floatx80 a ) static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status) { + floatx80 dflt; commonNaNT z; - if (floatx80_is_signaling_nan(a)) { + if (floatx80_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } if ( a.low >> 63 ) { @@ -1007,9 +1004,10 @@ static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status) z.low = 0; z.high = a.low << 1; } else { - z.sign = floatx80_default_nan_high >> 15; + dflt = floatx80_default_nan(status); + z.sign = dflt.high >> 15; z.low = 0; - z.high = floatx80_default_nan_low << 1; + z.high = dflt.low << 1; } return z; } @@ -1024,19 +1022,15 @@ static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status) floatx80 z; if (status->default_nan_mode) { - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; + return floatx80_default_nan(status); } if (a.high >> 1) { z.low = LIT64( 0x8000000000000000 ) | a.high >> 1; z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF; } else { - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; + z = floatx80_default_nan(status); } - return z; } @@ -1052,19 +1046,17 @@ static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; flag aIsLargerSignificand; - aIsQuietNaN = floatx80_is_quiet_nan( a ); - aIsSignalingNaN = floatx80_is_signaling_nan( a ); - bIsQuietNaN = floatx80_is_quiet_nan( b ); - bIsSignalingNaN = floatx80_is_signaling_nan( b ); + aIsQuietNaN = floatx80_is_quiet_nan(a, status); + aIsSignalingNaN = floatx80_is_signaling_nan(a, status); + bIsQuietNaN = floatx80_is_quiet_nan(b, status); + bIsSignalingNaN = floatx80_is_signaling_nan(b, status); if (aIsSignalingNaN | bIsSignalingNaN) { float_raise(float_flag_invalid, status); } if (status->default_nan_mode) { - a.low = floatx80_default_nan_low; - a.high = floatx80_default_nan_high; - return a; + return floatx80_default_nan(status); } if (a.low < b.low) { @@ -1077,19 +1069,19 @@ static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, aIsLargerSignificand)) { - return floatx80_maybe_silence_nan(b); + return floatx80_maybe_silence_nan(b, status); } else { - return floatx80_maybe_silence_nan(a); + return floatx80_maybe_silence_nan(a, status); } } #ifdef NO_SIGNALING_NANS -int float128_is_quiet_nan(float128 a_) +int float128_is_quiet_nan(float128 a_, float_status *status) { return float128_is_any_nan(a_); } -int float128_is_signaling_nan(float128 a_) +int float128_is_signaling_nan(float128 a_, float_status *status) { return 0; } @@ -1099,16 +1091,15 @@ int float128_is_signaling_nan(float128 a_) | NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float128_is_quiet_nan( float128 a ) +int float128_is_quiet_nan(float128 a, float_status *status) { -#if SNAN_BIT_IS_ONE - return (((a.high >> 47) & 0xffff) == 0xfffe) - && (a.low || (a.high & 0x00007fffffffffffULL)); -#else - return - ((a.high << 1) >= 0xffff000000000000ULL) - && (a.low || (a.high & 0x0000ffffffffffffULL)); -#endif + if (status->snan_bit_is_one) { + return (((a.high >> 47) & 0xFFFF) == 0xFFFE) + && (a.low || (a.high & 0x00007FFFFFFFFFFFULL)); + } else { + return ((a.high << 1) >= 0xFFFF000000000000ULL) + && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL)); + } } /*---------------------------------------------------------------------------- @@ -1116,17 +1107,15 @@ int float128_is_quiet_nan( float128 a ) | signaling NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -int float128_is_signaling_nan( float128 a ) +int float128_is_signaling_nan(float128 a, float_status *status) { -#if SNAN_BIT_IS_ONE - return - ((a.high << 1) >= 0xffff000000000000ULL) - && (a.low || (a.high & 0x0000ffffffffffffULL)); -#else - return - ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) - && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); -#endif + if (status->snan_bit_is_one) { + return ((a.high << 1) >= 0xFFFF000000000000ULL) + && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL)); + } else { + return (((a.high >> 47) & 0xFFFF) == 0xFFFE) + && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF))); + } } #endif @@ -1135,20 +1124,15 @@ int float128_is_signaling_nan( float128 a ) | a signaling NaN; otherwise returns `a'. *----------------------------------------------------------------------------*/ -float128 float128_maybe_silence_nan( float128 a ) +float128 float128_maybe_silence_nan(float128 a, float_status *status) { - if (float128_is_signaling_nan(a)) { -#if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) - a.low = float128_default_nan_low; - a.high = float128_default_nan_high; -# else -# error Rules for silencing a signaling NaN are target-specific -# endif -#else - a.high |= LIT64( 0x0000800000000000 ); - return a; -#endif + if (float128_is_signaling_nan(a, status)) { + if (status->snan_bit_is_one) { + a = float128_default_nan(status); + } else { + a.high |= LIT64(0x0000800000000000); + return a; + } } return a; } @@ -1163,7 +1147,7 @@ static commonNaNT float128ToCommonNaN(float128 a, float_status *status) { commonNaNT z; - if (float128_is_signaling_nan(a)) { + if (float128_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } z.sign = a.high>>63; @@ -1181,9 +1165,7 @@ static float128 commonNaNToFloat128(commonNaNT a, float_status *status) float128 z; if (status->default_nan_mode) { - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; + return float128_default_nan(status); } shift128Right( a.high, a.low, 16, &z.high, &z.low ); @@ -1203,19 +1185,17 @@ static float128 propagateFloat128NaN(float128 a, float128 b, flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; flag aIsLargerSignificand; - aIsQuietNaN = float128_is_quiet_nan( a ); - aIsSignalingNaN = float128_is_signaling_nan( a ); - bIsQuietNaN = float128_is_quiet_nan( b ); - bIsSignalingNaN = float128_is_signaling_nan( b ); + aIsQuietNaN = float128_is_quiet_nan(a, status); + aIsSignalingNaN = float128_is_signaling_nan(a, status); + bIsQuietNaN = float128_is_quiet_nan(b, status); + bIsSignalingNaN = float128_is_signaling_nan(b, status); if (aIsSignalingNaN | bIsSignalingNaN) { float_raise(float_flag_invalid, status); } if (status->default_nan_mode) { - a.low = float128_default_nan_low; - a.high = float128_default_nan_high; - return a; + return float128_default_nan(status); } if (lt128(a.high<<1, a.low, b.high<<1, b.low)) { @@ -1228,9 +1208,8 @@ static float128 propagateFloat128NaN(float128 a, float128 b, if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, aIsLargerSignificand)) { - return float128_maybe_silence_nan(b); + return float128_maybe_silence_nan(b, status); } else { - return float128_maybe_silence_nan(a); + return float128_maybe_silence_nan(a, status); } } - |