diff options
Diffstat (limited to 'fpu/softfloat-specialize.h')
| -rw-r--r-- | fpu/softfloat-specialize.h | 659 |
1 files changed, 333 insertions, 326 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index a4cbdad452..43d08903a5 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,106 @@ 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 + if (status->snan_bit_is_one) { + return const_float16(0x7DFF); + } else { +#if defined(TARGET_MIPS) + return const_float16(0x7E00); #else -const float16 float16_default_nan = const_float16(0xFE00); + return const_float16(0xFE00); #endif + } +#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 { +#if defined(TARGET_MIPS) + return const_float32(0x7FC00000); +#else + return const_float32(0xFFC00000); +#endif + } #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 + if (status->snan_bit_is_one) { + return const_float64(LIT64(0x7FF7FFFFFFFFFFFF)); + } else { +#if defined(TARGET_MIPS) + return const_float64(LIT64(0x7FF8000000000000)); #else -const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 )); + return const_float64(LIT64(0xFFF8000000000000)); #endif + } +#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 +211,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 +226,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 +241,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 +256,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,12 +280,12 @@ 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; z.low = 0; - z.high = ((uint64_t) float16_val(a))<<54; + z.high = ((uint64_t) float16_val(a)) << 54; return z; } @@ -277,27 +296,27 @@ static commonNaNT float16ToCommonNaN(float16 a, float_status *status) static float16 commonNaNToFloat16(commonNaNT a, float_status *status) { - uint16_t mantissa = a.high>>54; + 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 +326,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 +341,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 +357,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,12 +381,12 @@ 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; + z.sign = float32_val(a) >> 31; z.low = 0; - z.high = ( (uint64_t) float32_val(a) )<<41; + z.high = ((uint64_t)float32_val(a)) << 41; return z; } @@ -382,17 +397,18 @@ static commonNaNT float32ToCommonNaN(float32 a, float_status *status) static float32 commonNaNToFloat32(commonNaNT a, float_status *status) { - uint32_t mantissa = a.high>>41; + 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; + (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41)); + } else { + return float32_default_nan(status); + } } /*---------------------------------------------------------------------------- @@ -494,11 +510,10 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, return aIsLargerSignificand ? 0 : 1; } return bIsQNaN ? 1 : 0; - } - else if (aIsQNaN) { - if (bIsSNaN || !bIsQNaN) + } else if (aIsQNaN) { + if (bIsSNaN || !bIsQNaN) { return 0; - else { + } else { return aIsLargerSignificand ? 0 : 1; } } else { @@ -556,19 +571,36 @@ static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, 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; + if (status->snan_bit_is_one) { + /* 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; + } } else { - return 2; + /* Prefer sNaN over qNaN, in the c, a, b order. */ + if (cIsSNaN) { + return 2; + } else if (aIsSNaN) { + return 0; + } else if (bIsSNaN) { + return 1; + } else if (cIsQNaN) { + return 2; + } else if (aIsQNaN) { + return 0; + } else { + return 1; + } } } #elif defined(TARGET_PPC) @@ -626,10 +658,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,12 +669,13 @@ 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)) { + if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) { aIsLargerSignificand = 0; - } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) { + } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) { aIsLargerSignificand = 1; } else { aIsLargerSignificand = (av < bv) ? 1 : 0; @@ -650,9 +683,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 +706,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 +725,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 +757,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 +773,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 +790,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,12 +814,12 @@ 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; + z.sign = float64_val(a) >> 63; z.low = 0; - z.high = float64_val(a)<<12; + z.high = float64_val(a) << 12; return z; } @@ -802,19 +830,20 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status) static float64 commonNaNToFloat64(commonNaNT a, float_status *status) { - uint64_t mantissa = a.high>>12; + 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; + (((uint64_t) a.sign) << 63) + | LIT64(0x7FF0000000000000) + | (a.high >> 12)); + } else { + return float64_default_nan(status); + } } /*---------------------------------------------------------------------------- @@ -829,10 +858,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,12 +869,13 @@ 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)) { + if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) { aIsLargerSignificand = 0; - } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) { + } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) { aIsLargerSignificand = 1; } else { aIsLargerSignificand = (av < bv) ? 1 : 0; @@ -853,9 +883,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 +906,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 +925,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 +958,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 +979,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 +1000,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,19 +1021,21 @@ 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 ) { + if (a.low >> 63) { z.sign = a.high >> 15; 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 +1050,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; + 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 +1074,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 +1097,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 +1119,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 +1135,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 +1152,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,11 +1175,11 @@ 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; - shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); + z.sign = a.high >> 63; + shortShift128Left(a.high, a.low, 16, &z.high, &z.low); return z; } @@ -1181,13 +1193,11 @@ 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 ); - z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); + shift128Right(a.high, a.low, 16, &z.high, &z.low); + z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000); return z; } @@ -1203,24 +1213,22 @@ 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)) { + if (lt128(a.high << 1, a.low, b.high << 1, b.low)) { aIsLargerSignificand = 0; - } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) { + } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) { aIsLargerSignificand = 1; } else { aIsLargerSignificand = (a.high < b.high) ? 1 : 0; @@ -1228,9 +1236,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); } } - |