Home | History | Annotate | Line # | Download | only in softfloat
softfloat-specialize revision 1.9
      1  1.9      matt /*	$NetBSD: softfloat-specialize,v 1.9 2014/08/10 05:57:31 matt Exp $	*/
      2  1.3     bjh21 
      3  1.3     bjh21 /* This is a derivative work. */
      4  1.1     bjh21 
      5  1.1     bjh21 /*
      6  1.1     bjh21 ===============================================================================
      7  1.1     bjh21 
      8  1.1     bjh21 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
      9  1.1     bjh21 Arithmetic Package, Release 2a.
     10  1.1     bjh21 
     11  1.1     bjh21 Written by John R. Hauser.  This work was made possible in part by the
     12  1.1     bjh21 International Computer Science Institute, located at Suite 600, 1947 Center
     13  1.1     bjh21 Street, Berkeley, California 94704.  Funding was partially provided by the
     14  1.1     bjh21 National Science Foundation under grant MIP-9311980.  The original version
     15  1.1     bjh21 of this code was written as part of a project to build a fixed-point vector
     16  1.1     bjh21 processor in collaboration with the University of California at Berkeley,
     17  1.1     bjh21 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
     18  1.1     bjh21 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
     19  1.1     bjh21 arithmetic/SoftFloat.html'.
     20  1.1     bjh21 
     21  1.1     bjh21 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
     22  1.1     bjh21 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
     23  1.1     bjh21 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
     24  1.1     bjh21 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
     25  1.1     bjh21 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
     26  1.1     bjh21 
     27  1.1     bjh21 Derivative works are acceptable, even for commercial purposes, so long as
     28  1.1     bjh21 (1) they include prominent notice that the work is derivative, and (2) they
     29  1.1     bjh21 include prominent notice akin to these four paragraphs for those parts of
     30  1.1     bjh21 this code that are retained.
     31  1.1     bjh21 
     32  1.1     bjh21 ===============================================================================
     33  1.1     bjh21 */
     34  1.1     bjh21 
     35  1.3     bjh21 #include <signal.h>
     36  1.5    martin #include <string.h>
     37  1.5    martin #include <unistd.h>
     38  1.3     bjh21 
     39  1.1     bjh21 /*
     40  1.1     bjh21 -------------------------------------------------------------------------------
     41  1.1     bjh21 Underflow tininess-detection mode, statically initialized to default value.
     42  1.1     bjh21 (The declaration in `softfloat.h' must match the `int8' type here.)
     43  1.1     bjh21 -------------------------------------------------------------------------------
     44  1.1     bjh21 */
     45  1.1     bjh21 #ifdef SOFTFLOAT_FOR_GCC
     46  1.1     bjh21 static
     47  1.1     bjh21 #endif
     48  1.1     bjh21 int8 float_detect_tininess = float_tininess_after_rounding;
     49  1.1     bjh21 
     50  1.1     bjh21 /*
     51  1.1     bjh21 -------------------------------------------------------------------------------
     52  1.1     bjh21 Raises the exceptions specified by `flags'.  Floating-point traps can be
     53  1.1     bjh21 defined here if desired.  It is currently not possible for such a trap to
     54  1.1     bjh21 substitute a result value.  If traps are not implemented, this routine
     55  1.1     bjh21 should be simply `float_exception_flags |= flags;'.
     56  1.1     bjh21 -------------------------------------------------------------------------------
     57  1.1     bjh21 */
     58  1.6    martin #ifdef SOFTFLOAT_FOR_GCC
     59  1.8      matt #ifndef set_float_exception_mask
     60  1.6    martin #define float_exception_mask	_softfloat_float_exception_mask
     61  1.6    martin #endif
     62  1.8      matt #endif
     63  1.8      matt #ifndef set_float_exception_mask
     64  1.3     bjh21 fp_except float_exception_mask = 0;
     65  1.8      matt #endif
     66  1.8      matt void
     67  1.8      matt float_raise( fp_except flags )
     68  1.1     bjh21 {
     69  1.5    martin     siginfo_t info;
     70  1.8      matt     fp_except mask = float_exception_mask;
     71  1.1     bjh21 
     72  1.8      matt #ifdef set_float_exception_mask
     73  1.8      matt     flags |= set_float_exception_flags(flags, 0);
     74  1.8      matt #else
     75  1.1     bjh21     float_exception_flags |= flags;
     76  1.8      matt     flags = float_exception_flags;
     77  1.8      matt #endif
     78  1.1     bjh21 
     79  1.8      matt     flags &= mask;
     80  1.8      matt     if ( flags ) {
     81  1.5    martin 	memset(&info, 0, sizeof info);
     82  1.5    martin 	info.si_signo = SIGFPE;
     83  1.5    martin 	info.si_pid = getpid();
     84  1.5    martin 	info.si_uid = geteuid();
     85  1.5    martin 	if (flags & float_flag_underflow)
     86  1.5    martin 	    info.si_code = FPE_FLTUND;
     87  1.5    martin 	else if (flags & float_flag_overflow)
     88  1.5    martin 	    info.si_code = FPE_FLTOVF;
     89  1.5    martin 	else if (flags & float_flag_divbyzero)
     90  1.5    martin 	    info.si_code = FPE_FLTDIV;
     91  1.5    martin 	else if (flags & float_flag_invalid)
     92  1.5    martin 	    info.si_code = FPE_FLTINV;
     93  1.5    martin 	else if (flags & float_flag_inexact)
     94  1.5    martin 	    info.si_code = FPE_FLTRES;
     95  1.5    martin 	sigqueueinfo(getpid(), &info);
     96  1.3     bjh21     }
     97  1.1     bjh21 }
     98  1.6    martin #undef float_exception_mask
     99  1.1     bjh21 
    100  1.1     bjh21 /*
    101  1.1     bjh21 -------------------------------------------------------------------------------
    102  1.1     bjh21 Internal canonical NaN format.
    103  1.1     bjh21 -------------------------------------------------------------------------------
    104  1.1     bjh21 */
    105  1.1     bjh21 typedef struct {
    106  1.1     bjh21     flag sign;
    107  1.1     bjh21     bits64 high, low;
    108  1.1     bjh21 } commonNaNT;
    109  1.1     bjh21 
    110  1.1     bjh21 /*
    111  1.1     bjh21 -------------------------------------------------------------------------------
    112  1.1     bjh21 The pattern for a default generated single-precision NaN.
    113  1.1     bjh21 -------------------------------------------------------------------------------
    114  1.1     bjh21 */
    115  1.1     bjh21 #define float32_default_nan 0xFFFFFFFF
    116  1.1     bjh21 
    117  1.1     bjh21 /*
    118  1.1     bjh21 -------------------------------------------------------------------------------
    119  1.1     bjh21 Returns 1 if the single-precision floating-point value `a' is a NaN;
    120  1.1     bjh21 otherwise returns 0.
    121  1.1     bjh21 -------------------------------------------------------------------------------
    122  1.1     bjh21 */
    123  1.1     bjh21 #ifdef SOFTFLOAT_FOR_GCC
    124  1.1     bjh21 static
    125  1.1     bjh21 #endif
    126  1.1     bjh21 flag float32_is_nan( float32 a )
    127  1.1     bjh21 {
    128  1.1     bjh21 
    129  1.7  christos     return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) );
    130  1.1     bjh21 
    131  1.1     bjh21 }
    132  1.1     bjh21 
    133  1.1     bjh21 /*
    134  1.1     bjh21 -------------------------------------------------------------------------------
    135  1.1     bjh21 Returns 1 if the single-precision floating-point value `a' is a signaling
    136  1.1     bjh21 NaN; otherwise returns 0.
    137  1.1     bjh21 -------------------------------------------------------------------------------
    138  1.1     bjh21 */
    139  1.9      matt #if defined(SOFTFLOAT_FOR_GCC) \
    140  1.9      matt     && !defined(SOFTFLOATAARCH64_FOR_GCC) \
    141  1.9      matt     && !defined(SOFTFLOATSPARC64_FOR_GCC) \
    142  1.9      matt     && !defined(SOFTFLOATM68K_FOR_GCC)
    143  1.1     bjh21 static
    144  1.1     bjh21 #endif
    145  1.1     bjh21 flag float32_is_signaling_nan( float32 a )
    146  1.1     bjh21 {
    147  1.1     bjh21 
    148  1.1     bjh21     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
    149  1.1     bjh21 
    150  1.1     bjh21 }
    151  1.1     bjh21 
    152  1.1     bjh21 /*
    153  1.1     bjh21 -------------------------------------------------------------------------------
    154  1.1     bjh21 Returns the result of converting the single-precision floating-point NaN
    155  1.1     bjh21 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    156  1.1     bjh21 exception is raised.
    157  1.1     bjh21 -------------------------------------------------------------------------------
    158  1.1     bjh21 */
    159  1.1     bjh21 static commonNaNT float32ToCommonNaN( float32 a )
    160  1.1     bjh21 {
    161  1.1     bjh21     commonNaNT z;
    162  1.1     bjh21 
    163  1.1     bjh21     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    164  1.1     bjh21     z.sign = a>>31;
    165  1.1     bjh21     z.low = 0;
    166  1.1     bjh21     z.high = ( (bits64) a )<<41;
    167  1.1     bjh21     return z;
    168  1.1     bjh21 
    169  1.1     bjh21 }
    170  1.1     bjh21 
    171  1.1     bjh21 /*
    172  1.1     bjh21 -------------------------------------------------------------------------------
    173  1.1     bjh21 Returns the result of converting the canonical NaN `a' to the single-
    174  1.1     bjh21 precision floating-point format.
    175  1.1     bjh21 -------------------------------------------------------------------------------
    176  1.1     bjh21 */
    177  1.1     bjh21 static float32 commonNaNToFloat32( commonNaNT a )
    178  1.1     bjh21 {
    179  1.1     bjh21 
    180  1.7  christos     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 );
    181  1.1     bjh21 
    182  1.1     bjh21 }
    183  1.1     bjh21 
    184  1.1     bjh21 /*
    185  1.1     bjh21 -------------------------------------------------------------------------------
    186  1.1     bjh21 Takes two single-precision floating-point values `a' and `b', one of which
    187  1.1     bjh21 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    188  1.1     bjh21 signaling NaN, the invalid exception is raised.
    189  1.1     bjh21 -------------------------------------------------------------------------------
    190  1.1     bjh21 */
    191  1.1     bjh21 static float32 propagateFloat32NaN( float32 a, float32 b )
    192  1.1     bjh21 {
    193  1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    194  1.1     bjh21 
    195  1.1     bjh21     aIsNaN = float32_is_nan( a );
    196  1.1     bjh21     aIsSignalingNaN = float32_is_signaling_nan( a );
    197  1.1     bjh21     bIsNaN = float32_is_nan( b );
    198  1.1     bjh21     bIsSignalingNaN = float32_is_signaling_nan( b );
    199  1.1     bjh21     a |= 0x00400000;
    200  1.1     bjh21     b |= 0x00400000;
    201  1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    202  1.1     bjh21     if ( aIsNaN ) {
    203  1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    204  1.1     bjh21     }
    205  1.1     bjh21     else {
    206  1.1     bjh21         return b;
    207  1.1     bjh21     }
    208  1.1     bjh21 
    209  1.1     bjh21 }
    210  1.1     bjh21 
    211  1.1     bjh21 /*
    212  1.1     bjh21 -------------------------------------------------------------------------------
    213  1.1     bjh21 The pattern for a default generated double-precision NaN.
    214  1.1     bjh21 -------------------------------------------------------------------------------
    215  1.1     bjh21 */
    216  1.1     bjh21 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
    217  1.1     bjh21 
    218  1.1     bjh21 /*
    219  1.1     bjh21 -------------------------------------------------------------------------------
    220  1.1     bjh21 Returns 1 if the double-precision floating-point value `a' is a NaN;
    221  1.1     bjh21 otherwise returns 0.
    222  1.1     bjh21 -------------------------------------------------------------------------------
    223  1.1     bjh21 */
    224  1.1     bjh21 #ifdef SOFTFLOAT_FOR_GCC
    225  1.1     bjh21 static
    226  1.1     bjh21 #endif
    227  1.1     bjh21 flag float64_is_nan( float64 a )
    228  1.1     bjh21 {
    229  1.1     bjh21 
    230  1.7  christos     return ( (bits64)LIT64( 0xFFE0000000000000 ) <
    231  1.1     bjh21 	     (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
    232  1.1     bjh21 
    233  1.1     bjh21 }
    234  1.1     bjh21 
    235  1.1     bjh21 /*
    236  1.1     bjh21 -------------------------------------------------------------------------------
    237  1.1     bjh21 Returns 1 if the double-precision floating-point value `a' is a signaling
    238  1.1     bjh21 NaN; otherwise returns 0.
    239  1.1     bjh21 -------------------------------------------------------------------------------
    240  1.1     bjh21 */
    241  1.9      matt #if defined(SOFTFLOAT_FOR_GCC) \
    242  1.9      matt     && !defined(SOFTFLOATAARCH64_FOR_GCC) \
    243  1.9      matt     && !defined(SOFTFLOATSPARC64_FOR_GCC) \
    244  1.9      matt     && !defined(SOFTFLOATM68K_FOR_GCC)
    245  1.1     bjh21 static
    246  1.1     bjh21 #endif
    247  1.1     bjh21 flag float64_is_signaling_nan( float64 a )
    248  1.1     bjh21 {
    249  1.1     bjh21 
    250  1.1     bjh21     return
    251  1.1     bjh21            ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
    252  1.1     bjh21         && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
    253  1.1     bjh21 
    254  1.1     bjh21 }
    255  1.1     bjh21 
    256  1.1     bjh21 /*
    257  1.1     bjh21 -------------------------------------------------------------------------------
    258  1.1     bjh21 Returns the result of converting the double-precision floating-point NaN
    259  1.1     bjh21 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    260  1.1     bjh21 exception is raised.
    261  1.1     bjh21 -------------------------------------------------------------------------------
    262  1.1     bjh21 */
    263  1.1     bjh21 static commonNaNT float64ToCommonNaN( float64 a )
    264  1.1     bjh21 {
    265  1.1     bjh21     commonNaNT z;
    266  1.1     bjh21 
    267  1.1     bjh21     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    268  1.7  christos     z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63);
    269  1.1     bjh21     z.low = 0;
    270  1.1     bjh21     z.high = FLOAT64_DEMANGLE(a)<<12;
    271  1.1     bjh21     return z;
    272  1.1     bjh21 
    273  1.1     bjh21 }
    274  1.1     bjh21 
    275  1.1     bjh21 /*
    276  1.1     bjh21 -------------------------------------------------------------------------------
    277  1.1     bjh21 Returns the result of converting the canonical NaN `a' to the double-
    278  1.1     bjh21 precision floating-point format.
    279  1.1     bjh21 -------------------------------------------------------------------------------
    280  1.1     bjh21 */
    281  1.1     bjh21 static float64 commonNaNToFloat64( commonNaNT a )
    282  1.1     bjh21 {
    283  1.1     bjh21 
    284  1.1     bjh21     return FLOAT64_MANGLE(
    285  1.1     bjh21 	( ( (bits64) a.sign )<<63 )
    286  1.1     bjh21         | LIT64( 0x7FF8000000000000 )
    287  1.1     bjh21         | ( a.high>>12 ) );
    288  1.1     bjh21 
    289  1.1     bjh21 }
    290  1.1     bjh21 
    291  1.1     bjh21 /*
    292  1.1     bjh21 -------------------------------------------------------------------------------
    293  1.1     bjh21 Takes two double-precision floating-point values `a' and `b', one of which
    294  1.1     bjh21 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    295  1.1     bjh21 signaling NaN, the invalid exception is raised.
    296  1.1     bjh21 -------------------------------------------------------------------------------
    297  1.1     bjh21 */
    298  1.1     bjh21 static float64 propagateFloat64NaN( float64 a, float64 b )
    299  1.1     bjh21 {
    300  1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    301  1.1     bjh21 
    302  1.1     bjh21     aIsNaN = float64_is_nan( a );
    303  1.1     bjh21     aIsSignalingNaN = float64_is_signaling_nan( a );
    304  1.1     bjh21     bIsNaN = float64_is_nan( b );
    305  1.1     bjh21     bIsSignalingNaN = float64_is_signaling_nan( b );
    306  1.1     bjh21     a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
    307  1.1     bjh21     b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
    308  1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    309  1.1     bjh21     if ( aIsNaN ) {
    310  1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    311  1.1     bjh21     }
    312  1.1     bjh21     else {
    313  1.1     bjh21         return b;
    314  1.1     bjh21     }
    315  1.1     bjh21 
    316  1.1     bjh21 }
    317  1.1     bjh21 
    318  1.1     bjh21 #ifdef FLOATX80
    319  1.1     bjh21 
    320  1.1     bjh21 /*
    321  1.1     bjh21 -------------------------------------------------------------------------------
    322  1.1     bjh21 The pattern for a default generated extended double-precision NaN.  The
    323  1.1     bjh21 `high' and `low' values hold the most- and least-significant bits,
    324  1.1     bjh21 respectively.
    325  1.1     bjh21 -------------------------------------------------------------------------------
    326  1.1     bjh21 */
    327  1.1     bjh21 #define floatx80_default_nan_high 0xFFFF
    328  1.1     bjh21 #define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
    329  1.1     bjh21 
    330  1.1     bjh21 /*
    331  1.1     bjh21 -------------------------------------------------------------------------------
    332  1.1     bjh21 Returns 1 if the extended double-precision floating-point value `a' is a
    333  1.1     bjh21 NaN; otherwise returns 0.
    334  1.1     bjh21 -------------------------------------------------------------------------------
    335  1.1     bjh21 */
    336  1.1     bjh21 flag floatx80_is_nan( floatx80 a )
    337  1.1     bjh21 {
    338  1.1     bjh21 
    339  1.1     bjh21     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
    340  1.1     bjh21 
    341  1.1     bjh21 }
    342  1.1     bjh21 
    343  1.1     bjh21 /*
    344  1.1     bjh21 -------------------------------------------------------------------------------
    345  1.1     bjh21 Returns 1 if the extended double-precision floating-point value `a' is a
    346  1.1     bjh21 signaling NaN; otherwise returns 0.
    347  1.1     bjh21 -------------------------------------------------------------------------------
    348  1.1     bjh21 */
    349  1.1     bjh21 flag floatx80_is_signaling_nan( floatx80 a )
    350  1.1     bjh21 {
    351  1.1     bjh21     bits64 aLow;
    352  1.1     bjh21 
    353  1.1     bjh21     aLow = a.low & ~ LIT64( 0x4000000000000000 );
    354  1.1     bjh21     return
    355  1.1     bjh21            ( ( a.high & 0x7FFF ) == 0x7FFF )
    356  1.1     bjh21         && (bits64) ( aLow<<1 )
    357  1.1     bjh21         && ( a.low == aLow );
    358  1.1     bjh21 
    359  1.1     bjh21 }
    360  1.1     bjh21 
    361  1.1     bjh21 /*
    362  1.1     bjh21 -------------------------------------------------------------------------------
    363  1.1     bjh21 Returns the result of converting the extended double-precision floating-
    364  1.1     bjh21 point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
    365  1.1     bjh21 invalid exception is raised.
    366  1.1     bjh21 -------------------------------------------------------------------------------
    367  1.1     bjh21 */
    368  1.1     bjh21 static commonNaNT floatx80ToCommonNaN( floatx80 a )
    369  1.1     bjh21 {
    370  1.1     bjh21     commonNaNT z;
    371  1.1     bjh21 
    372  1.1     bjh21     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    373  1.1     bjh21     z.sign = a.high>>15;
    374  1.1     bjh21     z.low = 0;
    375  1.1     bjh21     z.high = a.low<<1;
    376  1.1     bjh21     return z;
    377  1.1     bjh21 
    378  1.1     bjh21 }
    379  1.1     bjh21 
    380  1.1     bjh21 /*
    381  1.1     bjh21 -------------------------------------------------------------------------------
    382  1.1     bjh21 Returns the result of converting the canonical NaN `a' to the extended
    383  1.1     bjh21 double-precision floating-point format.
    384  1.1     bjh21 -------------------------------------------------------------------------------
    385  1.1     bjh21 */
    386  1.1     bjh21 static floatx80 commonNaNToFloatx80( commonNaNT a )
    387  1.1     bjh21 {
    388  1.1     bjh21     floatx80 z;
    389  1.1     bjh21 
    390  1.1     bjh21     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
    391  1.1     bjh21     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
    392  1.1     bjh21     return z;
    393  1.1     bjh21 
    394  1.1     bjh21 }
    395  1.1     bjh21 
    396  1.1     bjh21 /*
    397  1.1     bjh21 -------------------------------------------------------------------------------
    398  1.1     bjh21 Takes two extended double-precision floating-point values `a' and `b', one
    399  1.1     bjh21 of which is a NaN, and returns the appropriate NaN result.  If either `a' or
    400  1.1     bjh21 `b' is a signaling NaN, the invalid exception is raised.
    401  1.1     bjh21 -------------------------------------------------------------------------------
    402  1.1     bjh21 */
    403  1.1     bjh21 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
    404  1.1     bjh21 {
    405  1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    406  1.1     bjh21 
    407  1.1     bjh21     aIsNaN = floatx80_is_nan( a );
    408  1.1     bjh21     aIsSignalingNaN = floatx80_is_signaling_nan( a );
    409  1.1     bjh21     bIsNaN = floatx80_is_nan( b );
    410  1.1     bjh21     bIsSignalingNaN = floatx80_is_signaling_nan( b );
    411  1.1     bjh21     a.low |= LIT64( 0xC000000000000000 );
    412  1.1     bjh21     b.low |= LIT64( 0xC000000000000000 );
    413  1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    414  1.1     bjh21     if ( aIsNaN ) {
    415  1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    416  1.1     bjh21     }
    417  1.1     bjh21     else {
    418  1.1     bjh21         return b;
    419  1.1     bjh21     }
    420  1.1     bjh21 
    421  1.1     bjh21 }
    422  1.1     bjh21 
    423  1.1     bjh21 #endif
    424  1.1     bjh21 
    425  1.1     bjh21 #ifdef FLOAT128
    426  1.1     bjh21 
    427  1.1     bjh21 /*
    428  1.1     bjh21 -------------------------------------------------------------------------------
    429  1.1     bjh21 The pattern for a default generated quadruple-precision NaN.  The `high' and
    430  1.1     bjh21 `low' values hold the most- and least-significant bits, respectively.
    431  1.1     bjh21 -------------------------------------------------------------------------------
    432  1.1     bjh21 */
    433  1.1     bjh21 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
    434  1.1     bjh21 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
    435  1.1     bjh21 
    436  1.1     bjh21 /*
    437  1.1     bjh21 -------------------------------------------------------------------------------
    438  1.1     bjh21 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
    439  1.1     bjh21 otherwise returns 0.
    440  1.1     bjh21 -------------------------------------------------------------------------------
    441  1.1     bjh21 */
    442  1.1     bjh21 flag float128_is_nan( float128 a )
    443  1.1     bjh21 {
    444  1.1     bjh21 
    445  1.1     bjh21     return
    446  1.7  christos            ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    447  1.1     bjh21         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    448  1.1     bjh21 
    449  1.1     bjh21 }
    450  1.1     bjh21 
    451  1.1     bjh21 /*
    452  1.1     bjh21 -------------------------------------------------------------------------------
    453  1.1     bjh21 Returns 1 if the quadruple-precision floating-point value `a' is a
    454  1.1     bjh21 signaling NaN; otherwise returns 0.
    455  1.1     bjh21 -------------------------------------------------------------------------------
    456  1.1     bjh21 */
    457  1.1     bjh21 flag float128_is_signaling_nan( float128 a )
    458  1.1     bjh21 {
    459  1.1     bjh21 
    460  1.1     bjh21     return
    461  1.1     bjh21            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    462  1.1     bjh21         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    463  1.1     bjh21 
    464  1.1     bjh21 }
    465  1.1     bjh21 
    466  1.1     bjh21 /*
    467  1.1     bjh21 -------------------------------------------------------------------------------
    468  1.1     bjh21 Returns the result of converting the quadruple-precision floating-point NaN
    469  1.1     bjh21 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    470  1.1     bjh21 exception is raised.
    471  1.1     bjh21 -------------------------------------------------------------------------------
    472  1.1     bjh21 */
    473  1.1     bjh21 static commonNaNT float128ToCommonNaN( float128 a )
    474  1.1     bjh21 {
    475  1.1     bjh21     commonNaNT z;
    476  1.1     bjh21 
    477  1.1     bjh21     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    478  1.7  christos     z.sign = (flag)(a.high>>63);
    479  1.1     bjh21     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
    480  1.1     bjh21     return z;
    481  1.1     bjh21 
    482  1.1     bjh21 }
    483  1.1     bjh21 
    484  1.1     bjh21 /*
    485  1.1     bjh21 -------------------------------------------------------------------------------
    486  1.1     bjh21 Returns the result of converting the canonical NaN `a' to the quadruple-
    487  1.1     bjh21 precision floating-point format.
    488  1.1     bjh21 -------------------------------------------------------------------------------
    489  1.1     bjh21 */
    490  1.1     bjh21 static float128 commonNaNToFloat128( commonNaNT a )
    491  1.1     bjh21 {
    492  1.1     bjh21     float128 z;
    493  1.1     bjh21 
    494  1.1     bjh21     shift128Right( a.high, a.low, 16, &z.high, &z.low );
    495  1.1     bjh21     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
    496  1.1     bjh21     return z;
    497  1.1     bjh21 
    498  1.1     bjh21 }
    499  1.1     bjh21 
    500  1.1     bjh21 /*
    501  1.1     bjh21 -------------------------------------------------------------------------------
    502  1.1     bjh21 Takes two quadruple-precision floating-point values `a' and `b', one of
    503  1.1     bjh21 which is a NaN, and returns the appropriate NaN result.  If either `a' or
    504  1.1     bjh21 `b' is a signaling NaN, the invalid exception is raised.
    505  1.1     bjh21 -------------------------------------------------------------------------------
    506  1.1     bjh21 */
    507  1.1     bjh21 static float128 propagateFloat128NaN( float128 a, float128 b )
    508  1.1     bjh21 {
    509  1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    510  1.1     bjh21 
    511  1.1     bjh21     aIsNaN = float128_is_nan( a );
    512  1.1     bjh21     aIsSignalingNaN = float128_is_signaling_nan( a );
    513  1.1     bjh21     bIsNaN = float128_is_nan( b );
    514  1.1     bjh21     bIsSignalingNaN = float128_is_signaling_nan( b );
    515  1.1     bjh21     a.high |= LIT64( 0x0000800000000000 );
    516  1.1     bjh21     b.high |= LIT64( 0x0000800000000000 );
    517  1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    518  1.1     bjh21     if ( aIsNaN ) {
    519  1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    520  1.1     bjh21     }
    521  1.1     bjh21     else {
    522  1.1     bjh21         return b;
    523  1.1     bjh21     }
    524  1.1     bjh21 
    525  1.1     bjh21 }
    526  1.1     bjh21 
    527  1.1     bjh21 #endif
    528  1.1     bjh21 
    529