symbian-qemu-0.9.1-12/qemu-symbian-svp/fpu/softfloat-specialize.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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