00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
00034 #define SNAN_BIT_IS_ONE 1
00035 #else
00036 #define SNAN_BIT_IS_ONE 0
00037 #endif
00038
00039
00040
00041
00042
00043
00044
00045
00046 void float_raise( int8 flags STATUS_PARAM )
00047 {
00048 STATUS(float_exception_flags) |= flags;
00049 }
00050
00051
00052
00053
00054 typedef struct {
00055 flag sign;
00056 bits64 high, low;
00057 } commonNaNT;
00058
00059
00060
00061
00062 #if defined(TARGET_SPARC)
00063 #define float32_default_nan make_float32(0x7FFFFFFF)
00064 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
00065 #define float32_default_nan make_float32(0x7FC00000)
00066 #elif defined(TARGET_HPPA)
00067 #define float32_default_nan make_float32(0x7FA00000)
00068 #elif SNAN_BIT_IS_ONE
00069 #define float32_default_nan make_float32(0x7FBFFFFF)
00070 #else
00071 #define float32_default_nan make_float32(0xFFC00000)
00072 #endif
00073
00074
00075
00076
00077
00078
00079 int float32_is_nan( float32 a_ )
00080 {
00081 uint32_t a = float32_val(a_);
00082 #if SNAN_BIT_IS_ONE
00083 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
00084 #else
00085 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
00086 #endif
00087 }
00088
00089
00090
00091
00092
00093
00094 int float32_is_signaling_nan( float32 a_ )
00095 {
00096 uint32_t a = float32_val(a_);
00097 #if SNAN_BIT_IS_ONE
00098 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
00099 #else
00100 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
00101 #endif
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
00111 {
00112 commonNaNT z;
00113
00114 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
00115 z.sign = float32_val(a)>>31;
00116 z.low = 0;
00117 z.high = ( (bits64) float32_val(a) )<<41;
00118 return z;
00119 }
00120
00121
00122
00123
00124
00125
00126 static float32 commonNaNToFloat32( commonNaNT a )
00127 {
00128 bits32 mantissa = a.high>>41;
00129 if ( mantissa )
00130 return make_float32(
00131 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
00132 else
00133 return float32_default_nan;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
00143 {
00144 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
00145 bits32 av, bv, res;
00146
00147 if ( STATUS(default_nan_mode) )
00148 return float32_default_nan;
00149
00150 aIsNaN = float32_is_nan( a );
00151 aIsSignalingNaN = float32_is_signaling_nan( a );
00152 bIsNaN = float32_is_nan( b );
00153 bIsSignalingNaN = float32_is_signaling_nan( b );
00154 av = float32_val(a);
00155 bv = float32_val(b);
00156 #if SNAN_BIT_IS_ONE
00157 av &= ~0x00400000;
00158 bv &= ~0x00400000;
00159 #else
00160 av |= 0x00400000;
00161 bv |= 0x00400000;
00162 #endif
00163 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
00164 if ( aIsSignalingNaN ) {
00165 if ( bIsSignalingNaN ) goto returnLargerSignificand;
00166 res = bIsNaN ? bv : av;
00167 }
00168 else if ( aIsNaN ) {
00169 if ( bIsSignalingNaN | ! bIsNaN )
00170 res = av;
00171 else {
00172 returnLargerSignificand:
00173 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
00174 res = bv;
00175 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
00176 res = av;
00177 else
00178 res = ( av < bv ) ? av : bv;
00179 }
00180 }
00181 else {
00182 res = bv;
00183 }
00184 return make_float32(res);
00185 }
00186
00187
00188
00189
00190 #if defined(TARGET_SPARC)
00191 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
00192 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
00193 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
00194 #elif defined(TARGET_HPPA)
00195 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
00196 #elif SNAN_BIT_IS_ONE
00197 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
00198 #else
00199 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
00200 #endif
00201
00202
00203
00204
00205
00206
00207 int float64_is_nan( float64 a_ )
00208 {
00209 bits64 a = float64_val(a_);
00210 #if SNAN_BIT_IS_ONE
00211 return
00212 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
00213 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
00214 #else
00215 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
00216 #endif
00217 }
00218
00219
00220
00221
00222
00223
00224 int float64_is_signaling_nan( float64 a_ )
00225 {
00226 bits64 a = float64_val(a_);
00227 #if SNAN_BIT_IS_ONE
00228 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
00229 #else
00230 return
00231 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
00232 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
00233 #endif
00234 }
00235
00236
00237
00238
00239
00240
00241
00242 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
00243 {
00244 commonNaNT z;
00245
00246 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
00247 z.sign = float64_val(a)>>63;
00248 z.low = 0;
00249 z.high = float64_val(a)<<12;
00250 return z;
00251 }
00252
00253
00254
00255
00256
00257
00258 static float64 commonNaNToFloat64( commonNaNT a )
00259 {
00260 bits64 mantissa = a.high>>12;
00261
00262 if ( mantissa )
00263 return make_float64(
00264 ( ( (bits64) a.sign )<<63 )
00265 | LIT64( 0x7FF0000000000000 )
00266 | ( a.high>>12 ));
00267 else
00268 return float64_default_nan;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
00278 {
00279 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
00280 bits64 av, bv, res;
00281
00282 if ( STATUS(default_nan_mode) )
00283 return float64_default_nan;
00284
00285 aIsNaN = float64_is_nan( a );
00286 aIsSignalingNaN = float64_is_signaling_nan( a );
00287 bIsNaN = float64_is_nan( b );
00288 bIsSignalingNaN = float64_is_signaling_nan( b );
00289 av = float64_val(a);
00290 bv = float64_val(b);
00291 #if SNAN_BIT_IS_ONE
00292 av &= ~LIT64( 0x0008000000000000 );
00293 bv &= ~LIT64( 0x0008000000000000 );
00294 #else
00295 av |= LIT64( 0x0008000000000000 );
00296 bv |= LIT64( 0x0008000000000000 );
00297 #endif
00298 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
00299 if ( aIsSignalingNaN ) {
00300 if ( bIsSignalingNaN ) goto returnLargerSignificand;
00301 res = bIsNaN ? bv : av;
00302 }
00303 else if ( aIsNaN ) {
00304 if ( bIsSignalingNaN | ! bIsNaN )
00305 res = av;
00306 else {
00307 returnLargerSignificand:
00308 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
00309 res = bv;
00310 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
00311 res = av;
00312 else
00313 res = ( av < bv ) ? av : bv;
00314 }
00315 }
00316 else {
00317 res = bv;
00318 }
00319 return make_float64(res);
00320 }
00321
00322 #ifdef FLOATX80
00323
00324
00325
00326
00327
00328
00329 #if SNAN_BIT_IS_ONE
00330 #define floatx80_default_nan_high 0x7FFF
00331 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
00332 #else
00333 #define floatx80_default_nan_high 0xFFFF
00334 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
00335 #endif
00336
00337
00338
00339
00340
00341
00342 int floatx80_is_nan( floatx80 a )
00343 {
00344 #if SNAN_BIT_IS_ONE
00345 bits64 aLow;
00346
00347 aLow = a.low & ~ LIT64( 0x4000000000000000 );
00348 return
00349 ( ( a.high & 0x7FFF ) == 0x7FFF )
00350 && (bits64) ( aLow<<1 )
00351 && ( a.low == aLow );
00352 #else
00353 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
00354 #endif
00355 }
00356
00357
00358
00359
00360
00361
00362 int floatx80_is_signaling_nan( floatx80 a )
00363 {
00364 #if SNAN_BIT_IS_ONE
00365 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
00366 #else
00367 bits64 aLow;
00368
00369 aLow = a.low & ~ LIT64( 0x4000000000000000 );
00370 return
00371 ( ( a.high & 0x7FFF ) == 0x7FFF )
00372 && (bits64) ( aLow<<1 )
00373 && ( a.low == aLow );
00374 #endif
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
00384 {
00385 commonNaNT z;
00386
00387 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
00388 z.sign = a.high>>15;
00389 z.low = 0;
00390 z.high = a.low;
00391 return z;
00392 }
00393
00394
00395
00396
00397
00398
00399 static floatx80 commonNaNToFloatx80( commonNaNT a )
00400 {
00401 floatx80 z;
00402
00403 if (a.high)
00404 z.low = a.high;
00405 else
00406 z.low = floatx80_default_nan_low;
00407 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
00408 return z;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
00418 {
00419 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
00420
00421 if ( STATUS(default_nan_mode) ) {
00422 a.low = floatx80_default_nan_low;
00423 a.high = floatx80_default_nan_high;
00424 return a;
00425 }
00426
00427 aIsNaN = floatx80_is_nan( a );
00428 aIsSignalingNaN = floatx80_is_signaling_nan( a );
00429 bIsNaN = floatx80_is_nan( b );
00430 bIsSignalingNaN = floatx80_is_signaling_nan( b );
00431 #if SNAN_BIT_IS_ONE
00432 a.low &= ~LIT64( 0xC000000000000000 );
00433 b.low &= ~LIT64( 0xC000000000000000 );
00434 #else
00435 a.low |= LIT64( 0xC000000000000000 );
00436 b.low |= LIT64( 0xC000000000000000 );
00437 #endif
00438 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
00439 if ( aIsSignalingNaN ) {
00440 if ( bIsSignalingNaN ) goto returnLargerSignificand;
00441 return bIsNaN ? b : a;
00442 }
00443 else if ( aIsNaN ) {
00444 if ( bIsSignalingNaN | ! bIsNaN ) return a;
00445 returnLargerSignificand:
00446 if ( a.low < b.low ) return b;
00447 if ( b.low < a.low ) return a;
00448 return ( a.high < b.high ) ? a : b;
00449 }
00450 else {
00451 return b;
00452 }
00453 }
00454
00455 #endif
00456
00457 #ifdef FLOAT128
00458
00459
00460
00461
00462
00463 #if SNAN_BIT_IS_ONE
00464 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
00465 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
00466 #else
00467 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
00468 #define float128_default_nan_low LIT64( 0x0000000000000000 )
00469 #endif
00470
00471
00472
00473
00474
00475
00476 int float128_is_nan( float128 a )
00477 {
00478 #if SNAN_BIT_IS_ONE
00479 return
00480 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
00481 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
00482 #else
00483 return
00484 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
00485 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
00486 #endif
00487 }
00488
00489
00490
00491
00492
00493
00494 int float128_is_signaling_nan( float128 a )
00495 {
00496 #if SNAN_BIT_IS_ONE
00497 return
00498 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
00499 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
00500 #else
00501 return
00502 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
00503 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
00504 #endif
00505 }
00506
00507
00508
00509
00510
00511
00512
00513 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
00514 {
00515 commonNaNT z;
00516
00517 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
00518 z.sign = a.high>>63;
00519 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
00520 return z;
00521 }
00522
00523
00524
00525
00526
00527
00528 static float128 commonNaNToFloat128( commonNaNT a )
00529 {
00530 float128 z;
00531
00532 shift128Right( a.high, a.low, 16, &z.high, &z.low );
00533 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
00534 return z;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
00544 {
00545 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
00546
00547 if ( STATUS(default_nan_mode) ) {
00548 a.low = float128_default_nan_low;
00549 a.high = float128_default_nan_high;
00550 return a;
00551 }
00552
00553 aIsNaN = float128_is_nan( a );
00554 aIsSignalingNaN = float128_is_signaling_nan( a );
00555 bIsNaN = float128_is_nan( b );
00556 bIsSignalingNaN = float128_is_signaling_nan( b );
00557 #if SNAN_BIT_IS_ONE
00558 a.high &= ~LIT64( 0x0000800000000000 );
00559 b.high &= ~LIT64( 0x0000800000000000 );
00560 #else
00561 a.high |= LIT64( 0x0000800000000000 );
00562 b.high |= LIT64( 0x0000800000000000 );
00563 #endif
00564 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
00565 if ( aIsSignalingNaN ) {
00566 if ( bIsSignalingNaN ) goto returnLargerSignificand;
00567 return bIsNaN ? b : a;
00568 }
00569 else if ( aIsNaN ) {
00570 if ( bIsSignalingNaN | ! bIsNaN ) return a;
00571 returnLargerSignificand:
00572 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
00573 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
00574 return ( a.high < b.high ) ? a : b;
00575 }
00576 else {
00577 return b;
00578 }
00579 }
00580
00581 #endif