Home | History | Annotate | Download | only in fpu
      1 
      2 /*============================================================================
      3 
      4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
      5 Arithmetic Package, Release 2b.
      6 
      7 Written by John R. Hauser.  This work was made possible in part by the
      8 International Computer Science Institute, located at Suite 600, 1947 Center
      9 Street, Berkeley, California 94704.  Funding was partially provided by the
     10 National Science Foundation under grant MIP-9311980.  The original version
     11 of this code was written as part of a project to build a fixed-point vector
     12 processor in collaboration with the University of California at Berkeley,
     13 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
     14 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
     15 arithmetic/SoftFloat.html'.
     16 
     17 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
     18 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
     19 RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
     20 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
     21 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
     22 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
     23 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
     24 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
     25 
     26 Derivative works are acceptable, even for commercial purposes, so long as
     27 (1) the source code for the derivative work includes prominent notice that
     28 the work is derivative, and (2) the source code includes prominent notice with
     29 these four paragraphs for those parts of this code that are retained.
     30 
     31 =============================================================================*/
     32 
     33 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
     34 #define SNAN_BIT_IS_ONE		1
     35 #else
     36 #define SNAN_BIT_IS_ONE		0
     37 #endif
     38 
     39 /*----------------------------------------------------------------------------
     40 | Raises the exceptions specified by `flags'.  Floating-point traps can be
     41 | defined here if desired.  It is currently not possible for such a trap
     42 | to substitute a result value.  If traps are not implemented, this routine
     43 | should be simply `float_exception_flags |= flags;'.
     44 *----------------------------------------------------------------------------*/
     45 
     46 void float_raise( int8 flags STATUS_PARAM )
     47 {
     48     STATUS(float_exception_flags) |= flags;
     49 }
     50 
     51 /*----------------------------------------------------------------------------
     52 | Internal canonical NaN format.
     53 *----------------------------------------------------------------------------*/
     54 typedef struct {
     55     flag sign;
     56     bits64 high, low;
     57 } commonNaNT;
     58 
     59 /*----------------------------------------------------------------------------
     60 | The pattern for a default generated single-precision NaN.
     61 *----------------------------------------------------------------------------*/
     62 #if defined(TARGET_SPARC)
     63 #define float32_default_nan make_float32(0x7FFFFFFF)
     64 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
     65 #define float32_default_nan make_float32(0x7FC00000)
     66 #elif defined(TARGET_HPPA)
     67 #define float32_default_nan make_float32(0x7FA00000)
     68 #elif SNAN_BIT_IS_ONE
     69 #define float32_default_nan make_float32(0x7FBFFFFF)
     70 #else
     71 #define float32_default_nan make_float32(0xFFC00000)
     72 #endif
     73 
     74 /*----------------------------------------------------------------------------
     75 | Returns 1 if the single-precision floating-point value `a' is a quiet
     76 | NaN; otherwise returns 0.
     77 *----------------------------------------------------------------------------*/
     78 
     79 int float32_is_nan( float32 a_ )
     80 {
     81     uint32_t a = float32_val(a_);
     82 #if SNAN_BIT_IS_ONE
     83     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
     84 #else
     85     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
     86 #endif
     87 }
     88 
     89 /*----------------------------------------------------------------------------
     90 | Returns 1 if the single-precision floating-point value `a' is a signaling
     91 | NaN; otherwise returns 0.
     92 *----------------------------------------------------------------------------*/
     93 
     94 int float32_is_signaling_nan( float32 a_ )
     95 {
     96     uint32_t a = float32_val(a_);
     97 #if SNAN_BIT_IS_ONE
     98     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
     99 #else
    100     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
    101 #endif
    102 }
    103 
    104 /*----------------------------------------------------------------------------
    105 | Returns the result of converting the single-precision floating-point NaN
    106 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    107 | exception is raised.
    108 *----------------------------------------------------------------------------*/
    109 
    110 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
    111 {
    112     commonNaNT z;
    113 
    114     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
    115     z.sign = float32_val(a)>>31;
    116     z.low = 0;
    117     z.high = ( (bits64) float32_val(a) )<<41;
    118     return z;
    119 }
    120 
    121 /*----------------------------------------------------------------------------
    122 | Returns the result of converting the canonical NaN `a' to the single-
    123 | precision floating-point format.
    124 *----------------------------------------------------------------------------*/
    125 
    126 static float32 commonNaNToFloat32( commonNaNT a )
    127 {
    128     bits32 mantissa = a.high>>41;
    129     if ( mantissa )
    130         return make_float32(
    131             ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
    132     else
    133         return float32_default_nan;
    134 }
    135 
    136 /*----------------------------------------------------------------------------
    137 | Takes two single-precision floating-point values `a' and `b', one of which
    138 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    139 | signaling NaN, the invalid exception is raised.
    140 *----------------------------------------------------------------------------*/
    141 
    142 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
    143 {
    144     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    145     bits32 av, bv, res;
    146 
    147     if ( STATUS(default_nan_mode) )
    148         return float32_default_nan;
    149 
    150     aIsNaN = float32_is_nan( a );
    151     aIsSignalingNaN = float32_is_signaling_nan( a );
    152     bIsNaN = float32_is_nan( b );
    153     bIsSignalingNaN = float32_is_signaling_nan( b );
    154     av = float32_val(a);
    155     bv = float32_val(b);
    156 #if SNAN_BIT_IS_ONE
    157     av &= ~0x00400000;
    158     bv &= ~0x00400000;
    159 #else
    160     av |= 0x00400000;
    161     bv |= 0x00400000;
    162 #endif
    163     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    164     if ( aIsSignalingNaN ) {
    165         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    166         res = bIsNaN ? bv : av;
    167     }
    168     else if ( aIsNaN ) {
    169         if ( bIsSignalingNaN || ! bIsNaN )
    170             res = av;
    171         else {
    172  returnLargerSignificand:
    173             if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
    174                 res = bv;
    175             else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
    176                 res = av;
    177             else
    178                 res = ( av < bv ) ? av : bv;
    179         }
    180     }
    181     else {
    182         res = bv;
    183     }
    184     return make_float32(res);
    185 }
    186 
    187 /*----------------------------------------------------------------------------
    188 | The pattern for a default generated double-precision NaN.
    189 *----------------------------------------------------------------------------*/
    190 #if defined(TARGET_SPARC)
    191 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
    192 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
    193 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
    194 #elif defined(TARGET_HPPA)
    195 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
    196 #elif SNAN_BIT_IS_ONE
    197 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
    198 #else
    199 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
    200 #endif
    201 
    202 /*----------------------------------------------------------------------------
    203 | Returns 1 if the double-precision floating-point value `a' is a quiet
    204 | NaN; otherwise returns 0.
    205 *----------------------------------------------------------------------------*/
    206 
    207 int float64_is_nan( float64 a_ )
    208 {
    209     bits64 a = float64_val(a_);
    210 #if SNAN_BIT_IS_ONE
    211     return
    212            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
    213         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
    214 #else
    215     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
    216 #endif
    217 }
    218 
    219 /*----------------------------------------------------------------------------
    220 | Returns 1 if the double-precision floating-point value `a' is a signaling
    221 | NaN; otherwise returns 0.
    222 *----------------------------------------------------------------------------*/
    223 
    224 int float64_is_signaling_nan( float64 a_ )
    225 {
    226     bits64 a = float64_val(a_);
    227 #if SNAN_BIT_IS_ONE
    228     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
    229 #else
    230     return
    231            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
    232         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
    233 #endif
    234 }
    235 
    236 /*----------------------------------------------------------------------------
    237 | Returns the result of converting the double-precision floating-point NaN
    238 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    239 | exception is raised.
    240 *----------------------------------------------------------------------------*/
    241 
    242 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
    243 {
    244     commonNaNT z;
    245 
    246     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
    247     z.sign = float64_val(a)>>63;
    248     z.low = 0;
    249     z.high = float64_val(a)<<12;
    250     return z;
    251 }
    252 
    253 /*----------------------------------------------------------------------------
    254 | Returns the result of converting the canonical NaN `a' to the double-
    255 | precision floating-point format.
    256 *----------------------------------------------------------------------------*/
    257 
    258 static float64 commonNaNToFloat64( commonNaNT a )
    259 {
    260     bits64 mantissa = a.high>>12;
    261 
    262     if ( mantissa )
    263         return make_float64(
    264               ( ( (bits64) a.sign )<<63 )
    265             | LIT64( 0x7FF0000000000000 )
    266             | ( a.high>>12 ));
    267     else
    268         return float64_default_nan;
    269 }
    270 
    271 /*----------------------------------------------------------------------------
    272 | Takes two double-precision floating-point values `a' and `b', one of which
    273 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    274 | signaling NaN, the invalid exception is raised.
    275 *----------------------------------------------------------------------------*/
    276 
    277 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
    278 {
    279     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    280     bits64 av, bv, res;
    281 
    282     if ( STATUS(default_nan_mode) )
    283         return float64_default_nan;
    284 
    285     aIsNaN = float64_is_nan( a );
    286     aIsSignalingNaN = float64_is_signaling_nan( a );
    287     bIsNaN = float64_is_nan( b );
    288     bIsSignalingNaN = float64_is_signaling_nan( b );
    289     av = float64_val(a);
    290     bv = float64_val(b);
    291 #if SNAN_BIT_IS_ONE
    292     av &= ~LIT64( 0x0008000000000000 );
    293     bv &= ~LIT64( 0x0008000000000000 );
    294 #else
    295     av |= LIT64( 0x0008000000000000 );
    296     bv |= LIT64( 0x0008000000000000 );
    297 #endif
    298     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    299     if ( aIsSignalingNaN ) {
    300         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    301         res = bIsNaN ? bv : av;
    302     }
    303     else if ( aIsNaN ) {
    304         if ( bIsSignalingNaN || ! bIsNaN )
    305             res = av;
    306         else {
    307  returnLargerSignificand:
    308             if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
    309                 res = bv;
    310             else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
    311                 res = av;
    312             else
    313                 res = ( av < bv ) ? av : bv;
    314         }
    315     }
    316     else {
    317         res = bv;
    318     }
    319     return make_float64(res);
    320 }
    321 
    322 #ifdef FLOATX80
    323 
    324 /*----------------------------------------------------------------------------
    325 | The pattern for a default generated extended double-precision NaN.  The
    326 | `high' and `low' values hold the most- and least-significant bits,
    327 | respectively.
    328 *----------------------------------------------------------------------------*/
    329 #if SNAN_BIT_IS_ONE
    330 #define floatx80_default_nan_high 0x7FFF
    331 #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
    332 #else
    333 #define floatx80_default_nan_high 0xFFFF
    334 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
    335 #endif
    336 
    337 /*----------------------------------------------------------------------------
    338 | Returns 1 if the extended double-precision floating-point value `a' is a
    339 | quiet NaN; otherwise returns 0.
    340 *----------------------------------------------------------------------------*/
    341 
    342 int floatx80_is_nan( floatx80 a )
    343 {
    344 #if SNAN_BIT_IS_ONE
    345     bits64 aLow;
    346 
    347     aLow = a.low & ~ LIT64( 0x4000000000000000 );
    348     return
    349            ( ( a.high & 0x7FFF ) == 0x7FFF )
    350         && (bits64) ( aLow<<1 )
    351         && ( a.low == aLow );
    352 #else
    353     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
    354 #endif
    355 }
    356 
    357 /*----------------------------------------------------------------------------
    358 | Returns 1 if the extended double-precision floating-point value `a' is a
    359 | signaling NaN; otherwise returns 0.
    360 *----------------------------------------------------------------------------*/
    361 
    362 int floatx80_is_signaling_nan( floatx80 a )
    363 {
    364 #if SNAN_BIT_IS_ONE
    365     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
    366 #else
    367     bits64 aLow;
    368 
    369     aLow = a.low & ~ LIT64( 0x4000000000000000 );
    370     return
    371            ( ( a.high & 0x7FFF ) == 0x7FFF )
    372         && (bits64) ( aLow<<1 )
    373         && ( a.low == aLow );
    374 #endif
    375 }
    376 
    377 /*----------------------------------------------------------------------------
    378 | Returns the result of converting the extended double-precision floating-
    379 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
    380 | invalid exception is raised.
    381 *----------------------------------------------------------------------------*/
    382 
    383 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
    384 {
    385     commonNaNT z;
    386 
    387     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
    388     z.sign = a.high>>15;
    389     z.low = 0;
    390     z.high = a.low;
    391     return z;
    392 }
    393 
    394 /*----------------------------------------------------------------------------
    395 | Returns the result of converting the canonical NaN `a' to the extended
    396 | double-precision floating-point format.
    397 *----------------------------------------------------------------------------*/
    398 
    399 static floatx80 commonNaNToFloatx80( commonNaNT a )
    400 {
    401     floatx80 z;
    402 
    403     if (a.high)
    404         z.low = a.high;
    405     else
    406         z.low = floatx80_default_nan_low;
    407     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
    408     return z;
    409 }
    410 
    411 /*----------------------------------------------------------------------------
    412 | Takes two extended double-precision floating-point values `a' and `b', one
    413 | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
    414 | `b' is a signaling NaN, the invalid exception is raised.
    415 *----------------------------------------------------------------------------*/
    416 
    417 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
    418 {
    419     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    420 
    421     if ( STATUS(default_nan_mode) ) {
    422         a.low = floatx80_default_nan_low;
    423         a.high = floatx80_default_nan_high;
    424         return a;
    425     }
    426 
    427     aIsNaN = floatx80_is_nan( a );
    428     aIsSignalingNaN = floatx80_is_signaling_nan( a );
    429     bIsNaN = floatx80_is_nan( b );
    430     bIsSignalingNaN = floatx80_is_signaling_nan( b );
    431 #if SNAN_BIT_IS_ONE
    432     a.low &= ~LIT64( 0xC000000000000000 );
    433     b.low &= ~LIT64( 0xC000000000000000 );
    434 #else
    435     a.low |= LIT64( 0xC000000000000000 );
    436     b.low |= LIT64( 0xC000000000000000 );
    437 #endif
    438     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    439     if ( aIsSignalingNaN ) {
    440         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    441         return bIsNaN ? b : a;
    442     }
    443     else if ( aIsNaN ) {
    444         if ( bIsSignalingNaN || ! bIsNaN ) return a;
    445  returnLargerSignificand:
    446         if ( a.low < b.low ) return b;
    447         if ( b.low < a.low ) return a;
    448         return ( a.high < b.high ) ? a : b;
    449     }
    450     else {
    451         return b;
    452     }
    453 }
    454 
    455 #endif
    456 
    457 #ifdef FLOAT128
    458 
    459 /*----------------------------------------------------------------------------
    460 | The pattern for a default generated quadruple-precision NaN.  The `high' and
    461 | `low' values hold the most- and least-significant bits, respectively.
    462 *----------------------------------------------------------------------------*/
    463 #if SNAN_BIT_IS_ONE
    464 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
    465 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
    466 #else
    467 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
    468 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
    469 #endif
    470 
    471 /*----------------------------------------------------------------------------
    472 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
    473 | NaN; otherwise returns 0.
    474 *----------------------------------------------------------------------------*/
    475 
    476 int float128_is_nan( float128 a )
    477 {
    478 #if SNAN_BIT_IS_ONE
    479     return
    480            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    481         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    482 #else
    483     return
    484            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    485         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    486 #endif
    487 }
    488 
    489 /*----------------------------------------------------------------------------
    490 | Returns 1 if the quadruple-precision floating-point value `a' is a
    491 | signaling NaN; otherwise returns 0.
    492 *----------------------------------------------------------------------------*/
    493 
    494 int float128_is_signaling_nan( float128 a )
    495 {
    496 #if SNAN_BIT_IS_ONE
    497     return
    498            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    499         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    500 #else
    501     return
    502            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    503         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    504 #endif
    505 }
    506 
    507 /*----------------------------------------------------------------------------
    508 | Returns the result of converting the quadruple-precision floating-point NaN
    509 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    510 | exception is raised.
    511 *----------------------------------------------------------------------------*/
    512 
    513 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
    514 {
    515     commonNaNT z;
    516 
    517     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
    518     z.sign = a.high>>63;
    519     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
    520     return z;
    521 }
    522 
    523 /*----------------------------------------------------------------------------
    524 | Returns the result of converting the canonical NaN `a' to the quadruple-
    525 | precision floating-point format.
    526 *----------------------------------------------------------------------------*/
    527 
    528 static float128 commonNaNToFloat128( commonNaNT a )
    529 {
    530     float128 z;
    531 
    532     shift128Right( a.high, a.low, 16, &z.high, &z.low );
    533     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
    534     return z;
    535 }
    536 
    537 /*----------------------------------------------------------------------------
    538 | Takes two quadruple-precision floating-point values `a' and `b', one of
    539 | which is a NaN, and returns the appropriate NaN result.  If either `a' or
    540 | `b' is a signaling NaN, the invalid exception is raised.
    541 *----------------------------------------------------------------------------*/
    542 
    543 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
    544 {
    545     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    546 
    547     if ( STATUS(default_nan_mode) ) {
    548         a.low = float128_default_nan_low;
    549         a.high = float128_default_nan_high;
    550         return a;
    551     }
    552 
    553     aIsNaN = float128_is_nan( a );
    554     aIsSignalingNaN = float128_is_signaling_nan( a );
    555     bIsNaN = float128_is_nan( b );
    556     bIsSignalingNaN = float128_is_signaling_nan( b );
    557 #if SNAN_BIT_IS_ONE
    558     a.high &= ~LIT64( 0x0000800000000000 );
    559     b.high &= ~LIT64( 0x0000800000000000 );
    560 #else
    561     a.high |= LIT64( 0x0000800000000000 );
    562     b.high |= LIT64( 0x0000800000000000 );
    563 #endif
    564     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
    565     if ( aIsSignalingNaN ) {
    566         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    567         return bIsNaN ? b : a;
    568     }
    569     else if ( aIsNaN ) {
    570         if ( bIsSignalingNaN || ! bIsNaN ) return a;
    571  returnLargerSignificand:
    572         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
    573         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
    574         return ( a.high < b.high ) ? a : b;
    575     }
    576     else {
    577         return b;
    578     }
    579 }
    580 
    581 #endif
    582