softfloat-specialize revision 1.9
11.9Smatt/*	$NetBSD: softfloat-specialize,v 1.9 2014/08/10 05:57:31 matt Exp $	*/
21.3Sbjh21
31.3Sbjh21/* This is a derivative work. */
41.1Sbjh21
51.1Sbjh21/*
61.1Sbjh21===============================================================================
71.1Sbjh21
81.1Sbjh21This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
91.1Sbjh21Arithmetic Package, Release 2a.
101.1Sbjh21
111.1Sbjh21Written by John R. Hauser.  This work was made possible in part by the
121.1Sbjh21International Computer Science Institute, located at Suite 600, 1947 Center
131.1Sbjh21Street, Berkeley, California 94704.  Funding was partially provided by the
141.1Sbjh21National Science Foundation under grant MIP-9311980.  The original version
151.1Sbjh21of this code was written as part of a project to build a fixed-point vector
161.1Sbjh21processor in collaboration with the University of California at Berkeley,
171.1Sbjh21overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
181.1Sbjh21is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
191.1Sbjh21arithmetic/SoftFloat.html'.
201.1Sbjh21
211.1Sbjh21THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
221.1Sbjh21has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
231.1Sbjh21TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
241.1Sbjh21PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
251.1Sbjh21AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
261.1Sbjh21
271.1Sbjh21Derivative works are acceptable, even for commercial purposes, so long as
281.1Sbjh21(1) they include prominent notice that the work is derivative, and (2) they
291.1Sbjh21include prominent notice akin to these four paragraphs for those parts of
301.1Sbjh21this code that are retained.
311.1Sbjh21
321.1Sbjh21===============================================================================
331.1Sbjh21*/
341.1Sbjh21
351.3Sbjh21#include <signal.h>
361.5Smartin#include <string.h>
371.5Smartin#include <unistd.h>
381.3Sbjh21
391.1Sbjh21/*
401.1Sbjh21-------------------------------------------------------------------------------
411.1Sbjh21Underflow tininess-detection mode, statically initialized to default value.
421.1Sbjh21(The declaration in `softfloat.h' must match the `int8' type here.)
431.1Sbjh21-------------------------------------------------------------------------------
441.1Sbjh21*/
451.1Sbjh21#ifdef SOFTFLOAT_FOR_GCC
461.1Sbjh21static
471.1Sbjh21#endif
481.1Sbjh21int8 float_detect_tininess = float_tininess_after_rounding;
491.1Sbjh21
501.1Sbjh21/*
511.1Sbjh21-------------------------------------------------------------------------------
521.1Sbjh21Raises the exceptions specified by `flags'.  Floating-point traps can be
531.1Sbjh21defined here if desired.  It is currently not possible for such a trap to
541.1Sbjh21substitute a result value.  If traps are not implemented, this routine
551.1Sbjh21should be simply `float_exception_flags |= flags;'.
561.1Sbjh21-------------------------------------------------------------------------------
571.1Sbjh21*/
581.6Smartin#ifdef SOFTFLOAT_FOR_GCC
591.8Smatt#ifndef set_float_exception_mask
601.6Smartin#define float_exception_mask	_softfloat_float_exception_mask
611.6Smartin#endif
621.8Smatt#endif
631.8Smatt#ifndef set_float_exception_mask
641.3Sbjh21fp_except float_exception_mask = 0;
651.8Smatt#endif
661.8Smattvoid
671.8Smattfloat_raise( fp_except flags )
681.1Sbjh21{
691.5Smartin    siginfo_t info;
701.8Smatt    fp_except mask = float_exception_mask;
711.1Sbjh21
721.8Smatt#ifdef set_float_exception_mask
731.8Smatt    flags |= set_float_exception_flags(flags, 0);
741.8Smatt#else
751.1Sbjh21    float_exception_flags |= flags;
761.8Smatt    flags = float_exception_flags;
771.8Smatt#endif
781.1Sbjh21
791.8Smatt    flags &= mask;
801.8Smatt    if ( flags ) {
811.5Smartin	memset(&info, 0, sizeof info);
821.5Smartin	info.si_signo = SIGFPE;
831.5Smartin	info.si_pid = getpid();
841.5Smartin	info.si_uid = geteuid();
851.5Smartin	if (flags & float_flag_underflow)
861.5Smartin	    info.si_code = FPE_FLTUND;
871.5Smartin	else if (flags & float_flag_overflow)
881.5Smartin	    info.si_code = FPE_FLTOVF;
891.5Smartin	else if (flags & float_flag_divbyzero)
901.5Smartin	    info.si_code = FPE_FLTDIV;
911.5Smartin	else if (flags & float_flag_invalid)
921.5Smartin	    info.si_code = FPE_FLTINV;
931.5Smartin	else if (flags & float_flag_inexact)
941.5Smartin	    info.si_code = FPE_FLTRES;
951.5Smartin	sigqueueinfo(getpid(), &info);
961.3Sbjh21    }
971.1Sbjh21}
981.6Smartin#undef float_exception_mask
991.1Sbjh21
1001.1Sbjh21/*
1011.1Sbjh21-------------------------------------------------------------------------------
1021.1Sbjh21Internal canonical NaN format.
1031.1Sbjh21-------------------------------------------------------------------------------
1041.1Sbjh21*/
1051.1Sbjh21typedef struct {
1061.1Sbjh21    flag sign;
1071.1Sbjh21    bits64 high, low;
1081.1Sbjh21} commonNaNT;
1091.1Sbjh21
1101.1Sbjh21/*
1111.1Sbjh21-------------------------------------------------------------------------------
1121.1Sbjh21The pattern for a default generated single-precision NaN.
1131.1Sbjh21-------------------------------------------------------------------------------
1141.1Sbjh21*/
1151.1Sbjh21#define float32_default_nan 0xFFFFFFFF
1161.1Sbjh21
1171.1Sbjh21/*
1181.1Sbjh21-------------------------------------------------------------------------------
1191.1Sbjh21Returns 1 if the single-precision floating-point value `a' is a NaN;
1201.1Sbjh21otherwise returns 0.
1211.1Sbjh21-------------------------------------------------------------------------------
1221.1Sbjh21*/
1231.1Sbjh21#ifdef SOFTFLOAT_FOR_GCC
1241.1Sbjh21static
1251.1Sbjh21#endif
1261.1Sbjh21flag float32_is_nan( float32 a )
1271.1Sbjh21{
1281.1Sbjh21
1291.7Schristos    return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) );
1301.1Sbjh21
1311.1Sbjh21}
1321.1Sbjh21
1331.1Sbjh21/*
1341.1Sbjh21-------------------------------------------------------------------------------
1351.1Sbjh21Returns 1 if the single-precision floating-point value `a' is a signaling
1361.1Sbjh21NaN; otherwise returns 0.
1371.1Sbjh21-------------------------------------------------------------------------------
1381.1Sbjh21*/
1391.9Smatt#if defined(SOFTFLOAT_FOR_GCC) \
1401.9Smatt    && !defined(SOFTFLOATAARCH64_FOR_GCC) \
1411.9Smatt    && !defined(SOFTFLOATSPARC64_FOR_GCC) \
1421.9Smatt    && !defined(SOFTFLOATM68K_FOR_GCC)
1431.1Sbjh21static
1441.1Sbjh21#endif
1451.1Sbjh21flag float32_is_signaling_nan( float32 a )
1461.1Sbjh21{
1471.1Sbjh21
1481.1Sbjh21    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
1491.1Sbjh21
1501.1Sbjh21}
1511.1Sbjh21
1521.1Sbjh21/*
1531.1Sbjh21-------------------------------------------------------------------------------
1541.1Sbjh21Returns the result of converting the single-precision floating-point NaN
1551.1Sbjh21`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
1561.1Sbjh21exception is raised.
1571.1Sbjh21-------------------------------------------------------------------------------
1581.1Sbjh21*/
1591.1Sbjh21static commonNaNT float32ToCommonNaN( float32 a )
1601.1Sbjh21{
1611.1Sbjh21    commonNaNT z;
1621.1Sbjh21
1631.1Sbjh21    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
1641.1Sbjh21    z.sign = a>>31;
1651.1Sbjh21    z.low = 0;
1661.1Sbjh21    z.high = ( (bits64) a )<<41;
1671.1Sbjh21    return z;
1681.1Sbjh21
1691.1Sbjh21}
1701.1Sbjh21
1711.1Sbjh21/*
1721.1Sbjh21-------------------------------------------------------------------------------
1731.1Sbjh21Returns the result of converting the canonical NaN `a' to the single-
1741.1Sbjh21precision floating-point format.
1751.1Sbjh21-------------------------------------------------------------------------------
1761.1Sbjh21*/
1771.1Sbjh21static float32 commonNaNToFloat32( commonNaNT a )
1781.1Sbjh21{
1791.1Sbjh21
1801.7Schristos    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 );
1811.1Sbjh21
1821.1Sbjh21}
1831.1Sbjh21
1841.1Sbjh21/*
1851.1Sbjh21-------------------------------------------------------------------------------
1861.1Sbjh21Takes two single-precision floating-point values `a' and `b', one of which
1871.1Sbjh21is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
1881.1Sbjh21signaling NaN, the invalid exception is raised.
1891.1Sbjh21-------------------------------------------------------------------------------
1901.1Sbjh21*/
1911.1Sbjh21static float32 propagateFloat32NaN( float32 a, float32 b )
1921.1Sbjh21{
1931.1Sbjh21    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
1941.1Sbjh21
1951.1Sbjh21    aIsNaN = float32_is_nan( a );
1961.1Sbjh21    aIsSignalingNaN = float32_is_signaling_nan( a );
1971.1Sbjh21    bIsNaN = float32_is_nan( b );
1981.1Sbjh21    bIsSignalingNaN = float32_is_signaling_nan( b );
1991.1Sbjh21    a |= 0x00400000;
2001.1Sbjh21    b |= 0x00400000;
2011.1Sbjh21    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
2021.1Sbjh21    if ( aIsNaN ) {
2031.1Sbjh21        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
2041.1Sbjh21    }
2051.1Sbjh21    else {
2061.1Sbjh21        return b;
2071.1Sbjh21    }
2081.1Sbjh21
2091.1Sbjh21}
2101.1Sbjh21
2111.1Sbjh21/*
2121.1Sbjh21-------------------------------------------------------------------------------
2131.1Sbjh21The pattern for a default generated double-precision NaN.
2141.1Sbjh21-------------------------------------------------------------------------------
2151.1Sbjh21*/
2161.1Sbjh21#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
2171.1Sbjh21
2181.1Sbjh21/*
2191.1Sbjh21-------------------------------------------------------------------------------
2201.1Sbjh21Returns 1 if the double-precision floating-point value `a' is a NaN;
2211.1Sbjh21otherwise returns 0.
2221.1Sbjh21-------------------------------------------------------------------------------
2231.1Sbjh21*/
2241.1Sbjh21#ifdef SOFTFLOAT_FOR_GCC
2251.1Sbjh21static
2261.1Sbjh21#endif
2271.1Sbjh21flag float64_is_nan( float64 a )
2281.1Sbjh21{
2291.1Sbjh21
2301.7Schristos    return ( (bits64)LIT64( 0xFFE0000000000000 ) <
2311.1Sbjh21	     (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
2321.1Sbjh21
2331.1Sbjh21}
2341.1Sbjh21
2351.1Sbjh21/*
2361.1Sbjh21-------------------------------------------------------------------------------
2371.1Sbjh21Returns 1 if the double-precision floating-point value `a' is a signaling
2381.1Sbjh21NaN; otherwise returns 0.
2391.1Sbjh21-------------------------------------------------------------------------------
2401.1Sbjh21*/
2411.9Smatt#if defined(SOFTFLOAT_FOR_GCC) \
2421.9Smatt    && !defined(SOFTFLOATAARCH64_FOR_GCC) \
2431.9Smatt    && !defined(SOFTFLOATSPARC64_FOR_GCC) \
2441.9Smatt    && !defined(SOFTFLOATM68K_FOR_GCC)
2451.1Sbjh21static
2461.1Sbjh21#endif
2471.1Sbjh21flag float64_is_signaling_nan( float64 a )
2481.1Sbjh21{
2491.1Sbjh21
2501.1Sbjh21    return
2511.1Sbjh21           ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
2521.1Sbjh21        && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
2531.1Sbjh21
2541.1Sbjh21}
2551.1Sbjh21
2561.1Sbjh21/*
2571.1Sbjh21-------------------------------------------------------------------------------
2581.1Sbjh21Returns the result of converting the double-precision floating-point NaN
2591.1Sbjh21`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
2601.1Sbjh21exception is raised.
2611.1Sbjh21-------------------------------------------------------------------------------
2621.1Sbjh21*/
2631.1Sbjh21static commonNaNT float64ToCommonNaN( float64 a )
2641.1Sbjh21{
2651.1Sbjh21    commonNaNT z;
2661.1Sbjh21
2671.1Sbjh21    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
2681.7Schristos    z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63);
2691.1Sbjh21    z.low = 0;
2701.1Sbjh21    z.high = FLOAT64_DEMANGLE(a)<<12;
2711.1Sbjh21    return z;
2721.1Sbjh21
2731.1Sbjh21}
2741.1Sbjh21
2751.1Sbjh21/*
2761.1Sbjh21-------------------------------------------------------------------------------
2771.1Sbjh21Returns the result of converting the canonical NaN `a' to the double-
2781.1Sbjh21precision floating-point format.
2791.1Sbjh21-------------------------------------------------------------------------------
2801.1Sbjh21*/
2811.1Sbjh21static float64 commonNaNToFloat64( commonNaNT a )
2821.1Sbjh21{
2831.1Sbjh21
2841.1Sbjh21    return FLOAT64_MANGLE(
2851.1Sbjh21	( ( (bits64) a.sign )<<63 )
2861.1Sbjh21        | LIT64( 0x7FF8000000000000 )
2871.1Sbjh21        | ( a.high>>12 ) );
2881.1Sbjh21
2891.1Sbjh21}
2901.1Sbjh21
2911.1Sbjh21/*
2921.1Sbjh21-------------------------------------------------------------------------------
2931.1Sbjh21Takes two double-precision floating-point values `a' and `b', one of which
2941.1Sbjh21is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
2951.1Sbjh21signaling NaN, the invalid exception is raised.
2961.1Sbjh21-------------------------------------------------------------------------------
2971.1Sbjh21*/
2981.1Sbjh21static float64 propagateFloat64NaN( float64 a, float64 b )
2991.1Sbjh21{
3001.1Sbjh21    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
3011.1Sbjh21
3021.1Sbjh21    aIsNaN = float64_is_nan( a );
3031.1Sbjh21    aIsSignalingNaN = float64_is_signaling_nan( a );
3041.1Sbjh21    bIsNaN = float64_is_nan( b );
3051.1Sbjh21    bIsSignalingNaN = float64_is_signaling_nan( b );
3061.1Sbjh21    a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
3071.1Sbjh21    b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
3081.1Sbjh21    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
3091.1Sbjh21    if ( aIsNaN ) {
3101.1Sbjh21        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
3111.1Sbjh21    }
3121.1Sbjh21    else {
3131.1Sbjh21        return b;
3141.1Sbjh21    }
3151.1Sbjh21
3161.1Sbjh21}
3171.1Sbjh21
3181.1Sbjh21#ifdef FLOATX80
3191.1Sbjh21
3201.1Sbjh21/*
3211.1Sbjh21-------------------------------------------------------------------------------
3221.1Sbjh21The pattern for a default generated extended double-precision NaN.  The
3231.1Sbjh21`high' and `low' values hold the most- and least-significant bits,
3241.1Sbjh21respectively.
3251.1Sbjh21-------------------------------------------------------------------------------
3261.1Sbjh21*/
3271.1Sbjh21#define floatx80_default_nan_high 0xFFFF
3281.1Sbjh21#define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
3291.1Sbjh21
3301.1Sbjh21/*
3311.1Sbjh21-------------------------------------------------------------------------------
3321.1Sbjh21Returns 1 if the extended double-precision floating-point value `a' is a
3331.1Sbjh21NaN; otherwise returns 0.
3341.1Sbjh21-------------------------------------------------------------------------------
3351.1Sbjh21*/
3361.1Sbjh21flag floatx80_is_nan( floatx80 a )
3371.1Sbjh21{
3381.1Sbjh21
3391.1Sbjh21    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
3401.1Sbjh21
3411.1Sbjh21}
3421.1Sbjh21
3431.1Sbjh21/*
3441.1Sbjh21-------------------------------------------------------------------------------
3451.1Sbjh21Returns 1 if the extended double-precision floating-point value `a' is a
3461.1Sbjh21signaling NaN; otherwise returns 0.
3471.1Sbjh21-------------------------------------------------------------------------------
3481.1Sbjh21*/
3491.1Sbjh21flag floatx80_is_signaling_nan( floatx80 a )
3501.1Sbjh21{
3511.1Sbjh21    bits64 aLow;
3521.1Sbjh21
3531.1Sbjh21    aLow = a.low & ~ LIT64( 0x4000000000000000 );
3541.1Sbjh21    return
3551.1Sbjh21           ( ( a.high & 0x7FFF ) == 0x7FFF )
3561.1Sbjh21        && (bits64) ( aLow<<1 )
3571.1Sbjh21        && ( a.low == aLow );
3581.1Sbjh21
3591.1Sbjh21}
3601.1Sbjh21
3611.1Sbjh21/*
3621.1Sbjh21-------------------------------------------------------------------------------
3631.1Sbjh21Returns the result of converting the extended double-precision floating-
3641.1Sbjh21point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
3651.1Sbjh21invalid exception is raised.
3661.1Sbjh21-------------------------------------------------------------------------------
3671.1Sbjh21*/
3681.1Sbjh21static commonNaNT floatx80ToCommonNaN( floatx80 a )
3691.1Sbjh21{
3701.1Sbjh21    commonNaNT z;
3711.1Sbjh21
3721.1Sbjh21    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
3731.1Sbjh21    z.sign = a.high>>15;
3741.1Sbjh21    z.low = 0;
3751.1Sbjh21    z.high = a.low<<1;
3761.1Sbjh21    return z;
3771.1Sbjh21
3781.1Sbjh21}
3791.1Sbjh21
3801.1Sbjh21/*
3811.1Sbjh21-------------------------------------------------------------------------------
3821.1Sbjh21Returns the result of converting the canonical NaN `a' to the extended
3831.1Sbjh21double-precision floating-point format.
3841.1Sbjh21-------------------------------------------------------------------------------
3851.1Sbjh21*/
3861.1Sbjh21static floatx80 commonNaNToFloatx80( commonNaNT a )
3871.1Sbjh21{
3881.1Sbjh21    floatx80 z;
3891.1Sbjh21
3901.1Sbjh21    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
3911.1Sbjh21    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
3921.1Sbjh21    return z;
3931.1Sbjh21
3941.1Sbjh21}
3951.1Sbjh21
3961.1Sbjh21/*
3971.1Sbjh21-------------------------------------------------------------------------------
3981.1Sbjh21Takes two extended double-precision floating-point values `a' and `b', one
3991.1Sbjh21of which is a NaN, and returns the appropriate NaN result.  If either `a' or
4001.1Sbjh21`b' is a signaling NaN, the invalid exception is raised.
4011.1Sbjh21-------------------------------------------------------------------------------
4021.1Sbjh21*/
4031.1Sbjh21static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
4041.1Sbjh21{
4051.1Sbjh21    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
4061.1Sbjh21
4071.1Sbjh21    aIsNaN = floatx80_is_nan( a );
4081.1Sbjh21    aIsSignalingNaN = floatx80_is_signaling_nan( a );
4091.1Sbjh21    bIsNaN = floatx80_is_nan( b );
4101.1Sbjh21    bIsSignalingNaN = floatx80_is_signaling_nan( b );
4111.1Sbjh21    a.low |= LIT64( 0xC000000000000000 );
4121.1Sbjh21    b.low |= LIT64( 0xC000000000000000 );
4131.1Sbjh21    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
4141.1Sbjh21    if ( aIsNaN ) {
4151.1Sbjh21        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
4161.1Sbjh21    }
4171.1Sbjh21    else {
4181.1Sbjh21        return b;
4191.1Sbjh21    }
4201.1Sbjh21
4211.1Sbjh21}
4221.1Sbjh21
4231.1Sbjh21#endif
4241.1Sbjh21
4251.1Sbjh21#ifdef FLOAT128
4261.1Sbjh21
4271.1Sbjh21/*
4281.1Sbjh21-------------------------------------------------------------------------------
4291.1Sbjh21The pattern for a default generated quadruple-precision NaN.  The `high' and
4301.1Sbjh21`low' values hold the most- and least-significant bits, respectively.
4311.1Sbjh21-------------------------------------------------------------------------------
4321.1Sbjh21*/
4331.1Sbjh21#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
4341.1Sbjh21#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
4351.1Sbjh21
4361.1Sbjh21/*
4371.1Sbjh21-------------------------------------------------------------------------------
4381.1Sbjh21Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
4391.1Sbjh21otherwise returns 0.
4401.1Sbjh21-------------------------------------------------------------------------------
4411.1Sbjh21*/
4421.1Sbjh21flag float128_is_nan( float128 a )
4431.1Sbjh21{
4441.1Sbjh21
4451.1Sbjh21    return
4461.7Schristos           ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
4471.1Sbjh21        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
4481.1Sbjh21
4491.1Sbjh21}
4501.1Sbjh21
4511.1Sbjh21/*
4521.1Sbjh21-------------------------------------------------------------------------------
4531.1Sbjh21Returns 1 if the quadruple-precision floating-point value `a' is a
4541.1Sbjh21signaling NaN; otherwise returns 0.
4551.1Sbjh21-------------------------------------------------------------------------------
4561.1Sbjh21*/
4571.1Sbjh21flag float128_is_signaling_nan( float128 a )
4581.1Sbjh21{
4591.1Sbjh21
4601.1Sbjh21    return
4611.1Sbjh21           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
4621.1Sbjh21        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
4631.1Sbjh21
4641.1Sbjh21}
4651.1Sbjh21
4661.1Sbjh21/*
4671.1Sbjh21-------------------------------------------------------------------------------
4681.1Sbjh21Returns the result of converting the quadruple-precision floating-point NaN
4691.1Sbjh21`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
4701.1Sbjh21exception is raised.
4711.1Sbjh21-------------------------------------------------------------------------------
4721.1Sbjh21*/
4731.1Sbjh21static commonNaNT float128ToCommonNaN( float128 a )
4741.1Sbjh21{
4751.1Sbjh21    commonNaNT z;
4761.1Sbjh21
4771.1Sbjh21    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
4781.7Schristos    z.sign = (flag)(a.high>>63);
4791.1Sbjh21    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
4801.1Sbjh21    return z;
4811.1Sbjh21
4821.1Sbjh21}
4831.1Sbjh21
4841.1Sbjh21/*
4851.1Sbjh21-------------------------------------------------------------------------------
4861.1Sbjh21Returns the result of converting the canonical NaN `a' to the quadruple-
4871.1Sbjh21precision floating-point format.
4881.1Sbjh21-------------------------------------------------------------------------------
4891.1Sbjh21*/
4901.1Sbjh21static float128 commonNaNToFloat128( commonNaNT a )
4911.1Sbjh21{
4921.1Sbjh21    float128 z;
4931.1Sbjh21
4941.1Sbjh21    shift128Right( a.high, a.low, 16, &z.high, &z.low );
4951.1Sbjh21    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
4961.1Sbjh21    return z;
4971.1Sbjh21
4981.1Sbjh21}
4991.1Sbjh21
5001.1Sbjh21/*
5011.1Sbjh21-------------------------------------------------------------------------------
5021.1Sbjh21Takes two quadruple-precision floating-point values `a' and `b', one of
5031.1Sbjh21which is a NaN, and returns the appropriate NaN result.  If either `a' or
5041.1Sbjh21`b' is a signaling NaN, the invalid exception is raised.
5051.1Sbjh21-------------------------------------------------------------------------------
5061.1Sbjh21*/
5071.1Sbjh21static float128 propagateFloat128NaN( float128 a, float128 b )
5081.1Sbjh21{
5091.1Sbjh21    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
5101.1Sbjh21
5111.1Sbjh21    aIsNaN = float128_is_nan( a );
5121.1Sbjh21    aIsSignalingNaN = float128_is_signaling_nan( a );
5131.1Sbjh21    bIsNaN = float128_is_nan( b );
5141.1Sbjh21    bIsSignalingNaN = float128_is_signaling_nan( b );
5151.1Sbjh21    a.high |= LIT64( 0x0000800000000000 );
5161.1Sbjh21    b.high |= LIT64( 0x0000800000000000 );
5171.1Sbjh21    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
5181.1Sbjh21    if ( aIsNaN ) {
5191.1Sbjh21        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
5201.1Sbjh21    }
5211.1Sbjh21    else {
5221.1Sbjh21        return b;
5231.1Sbjh21    }
5241.1Sbjh21
5251.1Sbjh21}
5261.1Sbjh21
5271.1Sbjh21#endif
5281.1Sbjh21
529