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