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