Changeset 36140 in vbox for trunk/src/recompiler/fpu
- Timestamp:
- Mar 3, 2011 1:48:16 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 70322
- Location:
- trunk/src/recompiler/fpu
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler/fpu/softfloat-macros.h
r21292 r36140 718 718 719 719 } 720 -
trunk/src/recompiler/fpu/softfloat-native.c
r21292 r36140 7 7 { 8 8 STATUS(float_rounding_mode) = val; 9 #if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && (HOST_SOLARIS < 10 || HOST_SOLARIS == 11)) 9 #if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && (HOST_SOLARIS < 10 || HOST_SOLARIS == 11)) /* VBOX adds sol 11 */ 10 10 fpsetround(val); 11 11 #elif defined(__arm__) … … 61 61 #endif 62 62 63 #if defined(_ ARCH_PPC)63 #if defined(__powerpc__) 64 64 65 65 /* correct (but slow) PowerPC rint() (glibc version is incorrect) */ 66 staticdouble qemu_rint(double x)66 double qemu_rint(double x) 67 67 { 68 68 double y = 4503599627370496.0; … … 230 230 { 231 231 if (a < b) { 232 return float_relation_less;232 return -1; 233 233 } else if (a == b) { 234 return float_relation_equal;234 return 0; 235 235 } else if (a > b) { 236 return float_relation_greater;237 } else { 238 return float_relation_unordered;236 return 1; 237 } else { 238 return 2; 239 239 } 240 240 } … … 242 242 { 243 243 if (isless(a, b)) { 244 return float_relation_less;244 return -1; 245 245 } else if (a == b) { 246 return float_relation_equal;246 return 0; 247 247 } else if (isgreater(a, b)) { 248 return float_relation_greater;249 } else { 250 return float_relation_unordered;248 return 1; 249 } else { 250 return 2; 251 251 } 252 252 } … … 258 258 a = u.i; 259 259 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 260 }261 262 int float32_is_nan( float32 a1 )263 {264 float32u u;265 uint64_t a;266 u.f = a1;267 a = u.i;268 return ( 0xFF800000 < ( a<<1 ) );269 260 } 270 261 … … 401 392 { 402 393 if (a < b) { 403 return float_relation_less;394 return -1; 404 395 } else if (a == b) { 405 return float_relation_equal;396 return 0; 406 397 } else if (a > b) { 407 return float_relation_greater;408 } else { 409 return float_relation_unordered;398 return 1; 399 } else { 400 return 2; 410 401 } 411 402 } … … 413 404 { 414 405 if (isless(a, b)) { 415 return float_relation_less;406 return -1; 416 407 } else if (a == b) { 417 return float_relation_equal;408 return 0; 418 409 } else if (isgreater(a, b)) { 419 return float_relation_greater;420 } else { 421 return float_relation_unordered;410 return 1; 411 } else { 412 return 2; 422 413 } 423 414 } … … 441 432 a = u.i; 442 433 443 return ( LIT64( 0xFF F0000000000000 ) < (bits64) ( a<<1 ) );434 return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); 444 435 445 436 } … … 493 484 { 494 485 if (a < b) { 495 return float_relation_less;486 return -1; 496 487 } else if (a == b) { 497 return float_relation_equal;488 return 0; 498 489 } else if (a > b) { 499 return float_relation_greater;500 } else { 501 return float_relation_unordered;490 return 1; 491 } else { 492 return 2; 502 493 } 503 494 } … … 505 496 { 506 497 if (isless(a, b)) { 507 return float_relation_less;498 return -1; 508 499 } else if (a == b) { 509 return float_relation_equal;500 return 0; 510 501 } else if (isgreater(a, b)) { 511 return float_relation_greater;512 } else { 513 return float_relation_unordered;502 return 1; 503 } else { 504 return 2; 514 505 } 515 506 } 516 507 int floatx80_is_signaling_nan( floatx80 a1) 517 {518 floatx80u u;519 uint64_t aLow;520 u.f = a1;521 522 aLow = u.i.low & ~ LIT64( 0x4000000000000000 );523 return524 ( ( u.i.high & 0x7FFF ) == 0x7FFF )525 && (bits64) ( aLow<<1 )526 && ( u.i.low == aLow );527 }528 529 int floatx80_is_nan( floatx80 a1 )530 508 { 531 509 floatx80u u; -
trunk/src/recompiler/fpu/softfloat-native.h
r36125 r36140 4 4 #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS) 5 5 #include <ieeefp.h> 6 #elif defined(_MSC_VER) 7 # include <fpieee.h> 8 # ifndef fabsf 9 # define fabsf(f) ((float)fabs(f)) 10 # endif 6 #define fabsf(f) ((float)fabs(f)) 11 7 #else 12 8 #include <fenv.h> 13 9 #endif 14 10 15 #if defined(__OpenBSD__) || defined(__NetBSD__) 11 #ifdef __OpenBSD__ 12 /* Get OpenBSD version number */ 16 13 #include <sys/param.h> 17 14 #endif … … 39 36 #endif 40 37 41 #ifdef __NetBSD__42 #ifndef isgreater43 #define isgreater(x, y) __builtin_isgreater(x, y)44 #endif45 #ifndef isgreaterequal46 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)47 #endif48 #ifndef isless49 #define isless(x, y) __builtin_isless(x, y)50 #endif51 #ifndef islessequal52 #define islessequal(x, y) __builtin_islessequal(x, y)53 #endif54 #ifndef isunordered55 #define isunordered(x, y) __builtin_isunordered(x, y)56 #endif57 #endif58 59 60 38 #define isnormal(x) (fpclass(x) >= FP_NZERO) 61 39 #define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y))) … … 145 123 146 124 typedef struct float_status { 147 intfloat_rounding_mode;148 #ifdef FLOATX80 149 intfloatx80_rounding_precision;125 signed char float_rounding_mode; 126 #ifdef FLOATX80 127 signed char floatx80_rounding_precision; 150 128 #endif 151 129 } float_status; … … 251 229 int float32_compare_quiet( float32, float32 STATUS_PARAM ); 252 230 int float32_is_signaling_nan( float32 ); 253 int float32_is_nan( float32 );254 231 255 232 INLINE float32 float32_abs(float32 a) … … 261 238 { 262 239 return -a; 263 }264 265 INLINE float32 float32_is_infinity(float32 a)266 {267 return fpclassify(a) == FP_INFINITE;268 }269 270 INLINE float32 float32_is_neg(float32 a)271 {272 float32u u;273 u.f = a;274 return u.i >> 31;275 }276 277 INLINE float32 float32_is_zero(float32 a)278 {279 return fpclassify(a) == FP_ZERO;280 240 } 281 241 … … 372 332 } 373 333 374 INLINE float64 float64_is_infinity(float64 a)375 {376 return fpclassify(a) == FP_INFINITE;377 }378 379 INLINE float64 float64_is_neg(float64 a)380 {381 float64u u;382 u.f = a;383 return u.i >> 63;384 }385 386 INLINE float64 float64_is_zero(float64 a)387 {388 return fpclassify(a) == FP_ZERO;389 }390 391 334 INLINE float64 float64_scalbn(float64 a, int n) 392 335 { … … 464 407 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM ); 465 408 int floatx80_is_signaling_nan( floatx80 ); 466 int floatx80_is_nan( floatx80 );467 409 468 410 INLINE floatx80 floatx80_abs(floatx80 a) … … 476 418 } 477 419 478 INLINE floatx80 floatx80_is_infinity(floatx80 a)479 {480 return fpclassify(a) == FP_INFINITE;481 }482 483 INLINE floatx80 floatx80_is_neg(floatx80 a)484 {485 floatx80u u;486 u.f = a;487 return u.i.high >> 15;488 }489 490 INLINE floatx80 floatx80_is_zero(floatx80 a)491 {492 return fpclassify(a) == FP_ZERO;493 }494 495 420 INLINE floatx80 floatx80_scalbn(floatx80 a, int n) 496 421 { -
trunk/src/recompiler/fpu/softfloat-specialize.h
r21292 r36140 38 38 39 39 /*---------------------------------------------------------------------------- 40 | Underflow tininess-detection mode, statically initialized to default value. 41 | (The declaration in `softfloat.h' must match the `int8' type here.) 42 *----------------------------------------------------------------------------*/ 43 int8 float_detect_tininess = float_tininess_after_rounding; 44 45 /*---------------------------------------------------------------------------- 40 46 | Raises the exceptions specified by `flags'. Floating-point traps can be 41 47 | defined here if desired. It is currently not possible for such a trap … … 62 68 #if defined(TARGET_SPARC) 63 69 #define float32_default_nan make_float32(0x7FFFFFFF) 64 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)70 #elif defined(TARGET_POWERPC) 65 71 #define float32_default_nan make_float32(0x7FC00000) 66 72 #elif defined(TARGET_HPPA) … … 144 150 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 145 151 bits32 av, bv, res; 146 147 if ( STATUS(default_nan_mode) )148 return float32_default_nan;149 152 150 153 aIsNaN = float32_is_nan( a ); … … 190 193 #if defined(TARGET_SPARC) 191 194 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF )) 192 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)195 #elif defined(TARGET_POWERPC) 193 196 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 )) 194 197 #elif defined(TARGET_HPPA) … … 279 282 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 280 283 bits64 av, bv, res; 281 282 if ( STATUS(default_nan_mode) )283 return float64_default_nan;284 284 285 285 aIsNaN = float64_is_nan( a ); … … 419 419 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 420 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 421 aIsNaN = floatx80_is_nan( a ); 428 422 aIsSignalingNaN = floatx80_is_signaling_nan( a ); … … 545 539 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 546 540 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 541 aIsNaN = float128_is_nan( a ); 554 542 aIsSignalingNaN = float128_is_signaling_nan( a ); -
trunk/src/recompiler/fpu/softfloat.c
r21292 r36140 31 31 =============================================================================*/ 32 32 33 /* FIXME: Flush-To-Zero only effects results. Denormal inputs should also34 be flushed to zero. */35 33 #include "softfloat.h" 36 34 … … 297 295 } 298 296 if ( zExp < 0 ) { 299 if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 );300 297 isTiny = 301 298 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 461 458 } 462 459 if ( zExp < 0 ) { 463 if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );464 460 isTiny = 465 461 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 640 636 } 641 637 if ( zExp <= 0 ) { 642 if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 );643 638 isTiny = 644 639 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 971 966 } 972 967 if ( zExp < 0 ) { 973 if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );974 968 isTiny = 975 969 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 1644 1638 return a; 1645 1639 } 1646 if ( aExp == 0 ) { 1647 if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 ); 1648 return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); 1649 } 1640 if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); 1650 1641 zSig = 0x40000000 + aSig + bSig; 1651 1642 zExp = aExp; … … 2055 2046 return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR ); 2056 2047 2057 }2058 2059 /*----------------------------------------------------------------------------2060 | Returns the binary log of the single-precision floating-point value `a'.2061 | The operation is performed according to the IEC/IEEE Standard for Binary2062 | Floating-Point Arithmetic.2063 *----------------------------------------------------------------------------*/2064 float32 float32_log2( float32 a STATUS_PARAM )2065 {2066 flag aSign, zSign;2067 int16 aExp;2068 bits32 aSig, zSig, i;2069 2070 aSig = extractFloat32Frac( a );2071 aExp = extractFloat32Exp( a );2072 aSign = extractFloat32Sign( a );2073 2074 if ( aExp == 0 ) {2075 if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );2076 normalizeFloat32Subnormal( aSig, &aExp, &aSig );2077 }2078 if ( aSign ) {2079 float_raise( float_flag_invalid STATUS_VAR);2080 return float32_default_nan;2081 }2082 if ( aExp == 0xFF ) {2083 if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );2084 return a;2085 }2086 2087 aExp -= 0x7F;2088 aSig |= 0x00800000;2089 zSign = aExp < 0;2090 zSig = aExp << 23;2091 2092 for (i = 1 << 22; i > 0; i >>= 1) {2093 aSig = ( (bits64)aSig * aSig ) >> 23;2094 if ( aSig & 0x01000000 ) {2095 aSig >>= 1;2096 zSig |= i;2097 }2098 }2099 2100 if ( zSign )2101 zSig = -zSig;2102 2103 return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );2104 2048 } 2105 2049 … … 2652 2596 return a; 2653 2597 } 2654 if ( aExp == 0 ) { 2655 if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 ); 2656 return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); 2657 } 2598 if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); 2658 2599 zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; 2659 2600 zExp = aExp; … … 3051 2992 return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR ); 3052 2993 3053 }3054 3055 /*----------------------------------------------------------------------------3056 | Returns the binary log of the double-precision floating-point value `a'.3057 | The operation is performed according to the IEC/IEEE Standard for Binary3058 | Floating-Point Arithmetic.3059 *----------------------------------------------------------------------------*/3060 float64 float64_log2( float64 a STATUS_PARAM )3061 {3062 flag aSign, zSign;3063 int16 aExp;3064 bits64 aSig, aSig0, aSig1, zSig, i;3065 3066 aSig = extractFloat64Frac( a );3067 aExp = extractFloat64Exp( a );3068 aSign = extractFloat64Sign( a );3069 3070 if ( aExp == 0 ) {3071 if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );3072 normalizeFloat64Subnormal( aSig, &aExp, &aSig );3073 }3074 if ( aSign ) {3075 float_raise( float_flag_invalid STATUS_VAR);3076 return float64_default_nan;3077 }3078 if ( aExp == 0x7FF ) {3079 if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );3080 return a;3081 }3082 3083 aExp -= 0x3FF;3084 aSig |= LIT64( 0x0010000000000000 );3085 zSign = aExp < 0;3086 zSig = (bits64)aExp << 52;3087 for (i = 1LL << 51; i > 0; i >>= 1) {3088 mul64To128( aSig, aSig, &aSig0, &aSig1 );3089 aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );3090 if ( aSig & LIT64( 0x0020000000000000 ) ) {3091 aSig >>= 1;3092 zSig |= i;3093 }3094 }3095 3096 if ( zSign )3097 zSig = -zSig;3098 return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );3099 2994 } 3100 2995 … … 4703 4598 } 4704 4599 add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); 4705 if ( aExp == 0 ) { 4706 if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 ); 4707 return packFloat128( zSign, 0, zSig0, zSig1 ); 4708 } 4600 if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); 4709 4601 zSig2 = 0; 4710 4602 zSig0 |= LIT64( 0x0002000000000000 ); … … 5588 5480 return a; 5589 5481 } 5590 if ( aExp != 0 ) 5591 aSig |= 0x00800000; 5592 else if ( aSig == 0 ) 5593 return a; 5594 5595 aExp += n - 1; 5596 aSig <<= 7; 5597 return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); 5482 aExp += n; 5483 return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); 5598 5484 } 5599 5485 … … 5611 5497 return a; 5612 5498 } 5613 if ( aExp != 0 ) 5614 aSig |= LIT64( 0x0010000000000000 ); 5615 else if ( aSig == 0 ) 5616 return a; 5617 5618 aExp += n - 1; 5619 aSig <<= 10; 5620 return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); 5499 aExp += n; 5500 return roundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); 5621 5501 } 5622 5502 … … 5635 5515 return a; 5636 5516 } 5637 if (aExp == 0 && aSig == 0)5638 return a;5639 5640 5517 aExp += n; 5641 return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),5642 5518 return roundAndPackFloatx80( STATUS(floatx80_rounding_precision), 5519 aSign, aExp, aSig, 0 STATUS_VAR ); 5643 5520 } 5644 5521 #endif … … 5658 5535 return a; 5659 5536 } 5660 if ( aExp != 0 ) 5661 aSig0 |= LIT64( 0x0001000000000000 ); 5662 else if ( aSig0 == 0 && aSig1 == 0 ) 5663 return a; 5664 5665 aExp += n - 1; 5666 return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1 5667 STATUS_VAR ); 5537 aExp += n; 5538 return roundAndPackFloat128( aSign, aExp, aSig0, aSig1, 0 STATUS_VAR ); 5668 5539 5669 5540 } -
trunk/src/recompiler/fpu/softfloat.h
r26499 r36140 55 55 typedef uint8_t uint8; 56 56 typedef int8_t int8; 57 #ifndef _AIX58 57 typedef int uint16; 59 58 typedef int int16; 60 #endif61 59 typedef unsigned int uint32; 62 60 typedef signed int int32; … … 95 93 #else 96 94 /* native float support */ 97 #if (defined(__i386__) || defined(__x86_64__)) && (!defined(_BSD) || defined(VBOX)) 95 #if (defined(__i386__) || defined(__x86_64__)) && (!defined(_BSD) || defined(VBOX)) /** @todo VBOX: not correct on windows */ 98 96 #define FLOATX80 99 97 #endif … … 199 197 signed char floatx80_rounding_precision; 200 198 #endif 201 flag flush_to_zero;202 flag default_nan_mode;203 199 } float_status; 204 200 205 201 void set_float_rounding_mode(int val STATUS_PARAM); 206 202 void set_float_exception_flags(int val STATUS_PARAM); 207 INLINE void set_flush_to_zero(flag val STATUS_PARAM)208 {209 STATUS(flush_to_zero) = val;210 }211 INLINE void set_default_nan_mode(flag val STATUS_PARAM)212 {213 STATUS(default_nan_mode) = val;214 }215 203 INLINE int get_float_exception_flags(float_status *status) 216 204 { … … 278 266 float32 float32_rem( float32, float32 STATUS_PARAM ); 279 267 float32 float32_sqrt( float32 STATUS_PARAM ); 280 float32 float32_log2( float32 STATUS_PARAM );281 268 int float32_eq( float32, float32 STATUS_PARAM ); 282 269 int float32_le( float32, float32 STATUS_PARAM ); … … 301 288 } 302 289 303 INLINE int float32_is_infinity(float32 a)304 {305 return (float32_val(a) & 0x7fffffff) == 0x7f800000;306 }307 308 INLINE int float32_is_neg(float32 a)309 {310 return float32_val(a) >> 31;311 }312 313 INLINE int float32_is_zero(float32 a)314 {315 return (float32_val(a) & 0x7fffffff) == 0;316 }317 318 290 #define float32_zero make_float32(0) 319 #define float32_one make_float32(0x3f800000)320 291 321 292 /*---------------------------------------------------------------------------- … … 349 320 float64 float64_rem( float64, float64 STATUS_PARAM ); 350 321 float64 float64_sqrt( float64 STATUS_PARAM ); 351 float64 float64_log2( float64 STATUS_PARAM );352 322 int float64_eq( float64, float64 STATUS_PARAM ); 353 323 int float64_le( float64, float64 STATUS_PARAM ); … … 372 342 } 373 343 374 INLINE int float64_is_infinity(float64 a)375 {376 return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;377 }378 379 INLINE int float64_is_neg(float64 a)380 {381 return float64_val(a) >> 63;382 }383 384 INLINE int float64_is_zero(float64 a)385 {386 return (float64_val(a) & 0x7fffffffffffffffLL) == 0;387 }388 389 344 #define float64_zero make_float64(0) 390 #define float64_one make_float64(0x3ff0000000000000LL)391 345 392 346 #ifdef FLOATX80 … … 435 389 a.high ^= 0x8000; 436 390 return a; 437 }438 439 INLINE int floatx80_is_infinity(floatx80 a)440 {441 return (a.high & 0x7fff) == 0x7fff && a.low == 0;442 }443 444 INLINE int floatx80_is_neg(floatx80 a)445 {446 return a.high >> 15;447 }448 449 INLINE int floatx80_is_zero(floatx80 a)450 {451 return (a.high & 0x7fff) == 0 && a.low == 0;452 391 } 453 392 … … 503 442 } 504 443 505 INLINE int float128_is_infinity(float128 a)506 {507 return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;508 }509 510 INLINE int float128_is_neg(float128 a)511 {512 return a.high >> 63;513 }514 515 INLINE int float128_is_zero(float128 a)516 {517 return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;518 }519 520 444 #endif 521 445
Note:
See TracChangeset
for help on using the changeset viewer.