Changeset 18985 in vbox for trunk/src/recompiler_new
- Timestamp:
- Apr 17, 2009 9:13:29 AM (16 years ago)
- Location:
- trunk/src/recompiler_new/fpu
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler_new/fpu/softfloat-macros.h
r1 r18985 718 718 719 719 } 720 -
trunk/src/recompiler_new/fpu/softfloat-native.c
r18967 r18985 38 38 # define sqrtl(f) (sqrt(f)) 39 39 # define remainderl(fa, fb) (remainder(fa, fb)) 40 # endif /* VBOX */ 41 #endif 42 43 #if defined(__powerpc__) 40 # endif /* VBOX && _BSD */ 41 42 #if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10 43 extern long double rintl(long double); 44 extern long double scalbnl(long double, int); 45 46 long long 47 llrintl(long double x) { 48 return ((long long) rintl(x)); 49 } 50 51 long 52 lrintl(long double x) { 53 return ((long) rintl(x)); 54 } 55 56 long double 57 ldexpl(long double x, int n) { 58 return (scalbnl(x, n)); 59 } 60 #endif 61 #endif 62 63 #if defined(_ARCH_PPC) 44 64 45 65 /* correct (but slow) PowerPC rint() (glibc version is incorrect) */ 46 double qemu_rint(double x)66 static double qemu_rint(double x) 47 67 { 48 68 double y = 4503599627370496.0; … … 68 88 } 69 89 90 float32 uint32_to_float32(unsigned int v STATUS_PARAM) 91 { 92 return (float32)v; 93 } 94 70 95 float64 int32_to_float64(int v STATUS_PARAM) 96 { 97 return (float64)v; 98 } 99 100 float64 uint32_to_float64(unsigned int v STATUS_PARAM) 71 101 { 72 102 return (float64)v; … … 83 113 return (float32)v; 84 114 } 115 float32 uint64_to_float32( uint64_t v STATUS_PARAM) 116 { 117 return (float32)v; 118 } 85 119 float64 int64_to_float64( int64_t v STATUS_PARAM) 120 { 121 return (float64)v; 122 } 123 float64 uint64_to_float64( uint64_t v STATUS_PARAM) 86 124 { 87 125 return (float64)v; … … 96 134 /* XXX: this code implements the x86 behaviour, not the IEEE one. */ 97 135 #if HOST_LONG_BITS == 32 98 #ifndef VBOX99 136 static inline int long_to_int32(long a) 100 #else /* VBOX */101 DECLINLINE(int) long_to_int32(long a)102 #endif /* VBOX */103 137 { 104 138 return a; 105 139 } 106 140 #else 107 #ifndef VBOX108 141 static inline int long_to_int32(long a) 109 #else /* VBOX */110 DECLINLINE(int) long_to_int32(long a)111 #endif /* VBOX */112 142 { 113 143 if (a != (int32_t)a) … … 149 179 #endif 150 180 181 unsigned int float32_to_uint32( float32 a STATUS_PARAM) 182 { 183 int64_t v; 184 unsigned int res; 185 186 v = llrintf(a); 187 if (v < 0) { 188 res = 0; 189 } else if (v > 0xffffffff) { 190 res = 0xffffffff; 191 } else { 192 res = v; 193 } 194 return res; 195 } 196 unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM) 197 { 198 int64_t v; 199 unsigned int res; 200 201 v = (int64_t)a; 202 if (v < 0) { 203 res = 0; 204 } else if (v > 0xffffffff) { 205 res = 0xffffffff; 206 } else { 207 res = v; 208 } 209 return res; 210 } 211 151 212 /*---------------------------------------------------------------------------- 152 213 | Software IEC/IEEE single-precision operations. … … 169 230 { 170 231 if (a < b) { 171 return -1;232 return float_relation_less; 172 233 } else if (a == b) { 173 return 0;234 return float_relation_equal; 174 235 } else if (a > b) { 175 return 1;176 } else { 177 return 2;236 return float_relation_greater; 237 } else { 238 return float_relation_unordered; 178 239 } 179 240 } … … 181 242 { 182 243 if (isless(a, b)) { 183 return -1;244 return float_relation_less; 184 245 } else if (a == b) { 185 return 0;246 return float_relation_equal; 186 247 } else if (isgreater(a, b)) { 187 return 1;188 } else { 189 return 2;248 return float_relation_greater; 249 } else { 250 return float_relation_unordered; 190 251 } 191 252 } … … 199 260 } 200 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 } 270 201 271 /*---------------------------------------------------------------------------- 202 272 | Software IEC/IEEE double-precision conversion routines. … … 235 305 #endif 236 306 307 unsigned int float64_to_uint32( float64 a STATUS_PARAM) 308 { 309 int64_t v; 310 unsigned int res; 311 312 v = llrint(a); 313 if (v < 0) { 314 res = 0; 315 } else if (v > 0xffffffff) { 316 res = 0xffffffff; 317 } else { 318 res = v; 319 } 320 return res; 321 } 322 unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM) 323 { 324 int64_t v; 325 unsigned int res; 326 327 v = (int64_t)a; 328 if (v < 0) { 329 res = 0; 330 } else if (v > 0xffffffff) { 331 res = 0xffffffff; 332 } else { 333 res = v; 334 } 335 return res; 336 } 337 uint64_t float64_to_uint64 (float64 a STATUS_PARAM) 338 { 339 int64_t v; 340 341 v = llrint(a + (float64)INT64_MIN); 342 343 return v - INT64_MIN; 344 } 345 uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) 346 { 347 int64_t v; 348 349 v = (int64_t)(a + (float64)INT64_MIN); 350 351 return v - INT64_MIN; 352 } 353 237 354 /*---------------------------------------------------------------------------- 238 355 | Software IEC/IEEE double-precision operations. 239 356 *----------------------------------------------------------------------------*/ 357 #if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10 358 static inline float64 trunc(float64 x) 359 { 360 return x < 0 ? -floor(-x) : floor(x); 361 } 362 #endif 240 363 float64 float64_trunc_to_int( float64 a STATUS_PARAM ) 241 364 { … … 278 401 { 279 402 if (a < b) { 280 return -1;403 return float_relation_less; 281 404 } else if (a == b) { 282 return 0;405 return float_relation_equal; 283 406 } else if (a > b) { 284 return 1;285 } else { 286 return 2;407 return float_relation_greater; 408 } else { 409 return float_relation_unordered; 287 410 } 288 411 } … … 290 413 { 291 414 if (isless(a, b)) { 292 return -1;415 return float_relation_less; 293 416 } else if (a == b) { 294 return 0;417 return float_relation_equal; 295 418 } else if (isgreater(a, b)) { 296 return 1;297 } else { 298 return 2;419 return float_relation_greater; 420 } else { 421 return float_relation_unordered; 299 422 } 300 423 } … … 318 441 a = u.i; 319 442 320 return ( LIT64( 0xFF E0000000000000 ) < (bits64) ( a<<1 ) );443 return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) ); 321 444 322 445 } … … 370 493 { 371 494 if (a < b) { 372 return -1;495 return float_relation_less; 373 496 } else if (a == b) { 374 return 0;497 return float_relation_equal; 375 498 } else if (a > b) { 376 return 1;377 } else { 378 return 2;499 return float_relation_greater; 500 } else { 501 return float_relation_unordered; 379 502 } 380 503 } … … 382 505 { 383 506 if (isless(a, b)) { 384 return -1;507 return float_relation_less; 385 508 } else if (a == b) { 386 return 0;509 return float_relation_equal; 387 510 } else if (isgreater(a, b)) { 388 return 1;389 } else { 390 return 2;511 return float_relation_greater; 512 } else { 513 return float_relation_unordered; 391 514 } 392 515 } 393 516 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 return 524 ( ( u.i.high & 0x7FFF ) == 0x7FFF ) 525 && (bits64) ( aLow<<1 ) 526 && ( u.i.low == aLow ); 527 } 528 529 int floatx80_is_nan( floatx80 a1 ) 394 530 { 395 531 floatx80u u; -
trunk/src/recompiler_new/fpu/softfloat-native.h
r14447 r18985 3 3 4 4 #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS) 5 # include <ieeefp.h> 6 # define fabsf(f) ((float)fabs(f)) 5 #include <ieeefp.h> 7 6 #elif defined(_MSC_VER) 8 7 # include <fpieee.h> … … 11 10 # endif 12 11 #else 13 # include <fenv.h> 12 #include <fenv.h> 13 #endif 14 15 #if defined(__OpenBSD__) || defined(__NetBSD__) 16 #include <sys/param.h> 14 17 #endif 15 18 … … 21 24 * are defined in <iso/math_c99.h> with a compiler directive 22 25 */ 23 #if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ( ( HOST_SOLARIS >= 10 ) && ( __GNUC__ <= 4) )) 26 #if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) \ 27 && (__GNUC__ <= 4))) \ 28 || (defined(__OpenBSD__) && (OpenBSD < 200811)) 24 29 /* 25 30 * C99 7.12.3 classification macros … … 30 35 * Try to workaround the missing / broken C99 math macros. 31 36 */ 37 #if defined(__OpenBSD__) 38 #define unordered(x, y) (isnan(x) || isnan(y)) 39 #endif 40 41 #ifdef __NetBSD__ 42 #ifndef isgreater 43 #define isgreater(x, y) __builtin_isgreater(x, y) 44 #endif 45 #ifndef isgreaterequal 46 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y) 47 #endif 48 #ifndef isless 49 #define isless(x, y) __builtin_isless(x, y) 50 #endif 51 #ifndef islessequal 52 #define islessequal(x, y) __builtin_islessequal(x, y) 53 #endif 54 #ifndef isunordered 55 #define isunordered(x, y) __builtin_isunordered(x, y) 56 #endif 57 #endif 58 32 59 33 60 #define isnormal(x) (fpclass(x) >= FP_NZERO) … … 37 64 #define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y))) 38 65 #define isunordered(x,y) unordered(x, y) 39 #define isinf(x) ((fpclass(x) == FP_NINF) || (fpclass(x) == FP_PINF))40 41 66 #elif defined(_MSC_VER) 42 67 #include <float.h> … … 45 70 #define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y))) 46 71 #define isunordered(x,y) unordered(x, y) 72 #endif 73 74 #if defined(__sun__) && !defined(NEED_LIBSUNMATH) 75 76 #ifndef isnan 77 # define isnan(x) \ 78 (sizeof (x) == sizeof (long double) ? isnan_ld (x) \ 79 : sizeof (x) == sizeof (double) ? isnan_d (x) \ 80 : isnan_f (x)) 81 static inline int isnan_f (float x) { return x != x; } 82 static inline int isnan_d (double x) { return x != x; } 83 static inline int isnan_ld (long double x) { return x != x; } 84 #endif 85 86 #ifndef isinf 87 # define isinf(x) \ 88 (sizeof (x) == sizeof (long double) ? isinf_ld (x) \ 89 : sizeof (x) == sizeof (double) ? isinf_d (x) \ 90 : isinf_f (x)) 91 static inline int isinf_f (float x) { return isnan (x - x); } 92 static inline int isinf_d (double x) { return isnan (x - x); } 93 static inline int isinf_ld (long double x) { return isnan (x - x); } 94 #endif 47 95 #endif 48 96 … … 75 123 *----------------------------------------------------------------------------*/ 76 124 #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS) 125 #if defined(__OpenBSD__) 126 #define FE_RM FP_RM 127 #define FE_RP FP_RP 128 #define FE_RZ FP_RZ 129 #endif 77 130 enum { 78 131 float_round_nearest_even = FP_RN, … … 105 158 106 159 typedef struct float_status { 107 signed charfloat_rounding_mode;108 #ifdef FLOATX80 109 signed charfloatx80_rounding_precision;160 int float_rounding_mode; 161 #ifdef FLOATX80 162 int floatx80_rounding_precision; 110 163 #endif 111 164 } float_status; … … 120 173 *----------------------------------------------------------------------------*/ 121 174 float32 int32_to_float32( int STATUS_PARAM); 175 float32 uint32_to_float32( unsigned int STATUS_PARAM); 122 176 float64 int32_to_float64( int STATUS_PARAM); 177 float64 uint32_to_float64( unsigned int STATUS_PARAM); 123 178 #ifdef FLOATX80 124 179 floatx80 int32_to_floatx80( int STATUS_PARAM); … … 128 183 #endif 129 184 float32 int64_to_float32( int64_t STATUS_PARAM); 185 float32 uint64_to_float32( uint64_t STATUS_PARAM); 130 186 float64 int64_to_float64( int64_t STATUS_PARAM); 187 float64 uint64_to_float64( uint64_t v STATUS_PARAM); 131 188 #ifdef FLOATX80 132 189 floatx80 int64_to_floatx80( int64_t STATUS_PARAM); … … 141 198 int float32_to_int32( float32 STATUS_PARAM); 142 199 int float32_to_int32_round_to_zero( float32 STATUS_PARAM); 200 unsigned int float32_to_uint32( float32 a STATUS_PARAM); 201 unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM); 143 202 int64_t float32_to_int64( float32 STATUS_PARAM); 144 203 int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM); … … 205 264 int float32_compare_quiet( float32, float32 STATUS_PARAM ); 206 265 int float32_is_signaling_nan( float32 ); 266 int float32_is_nan( float32 ); 207 267 208 268 INLINE float32 float32_abs(float32 a) … … 214 274 { 215 275 return -a; 276 } 277 278 INLINE float32 float32_is_infinity(float32 a) 279 { 280 return fpclassify(a) == FP_INFINITE; 281 } 282 283 INLINE float32 float32_is_neg(float32 a) 284 { 285 float32u u; 286 u.f = a; 287 return u.i >> 31; 288 } 289 290 INLINE float32 float32_is_zero(float32 a) 291 { 292 return fpclassify(a) == FP_ZERO; 293 } 294 295 INLINE float32 float32_scalbn(float32 a, int n) 296 { 297 return scalbnf(a, n); 216 298 } 217 299 … … 221 303 int float64_to_int32( float64 STATUS_PARAM ); 222 304 int float64_to_int32_round_to_zero( float64 STATUS_PARAM ); 305 unsigned int float64_to_uint32( float64 STATUS_PARAM ); 306 unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); 223 307 int64_t float64_to_int64( float64 STATUS_PARAM ); 224 308 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM ); 309 uint64_t float64_to_uint64( float64 STATUS_PARAM ); 310 uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM ); 225 311 float32 float64_to_float32( float64 STATUS_PARAM ); 226 312 #ifdef FLOATX80 … … 297 383 { 298 384 return -a; 385 } 386 387 INLINE float64 float64_is_infinity(float64 a) 388 { 389 return fpclassify(a) == FP_INFINITE; 390 } 391 392 INLINE float64 float64_is_neg(float64 a) 393 { 394 float64u u; 395 u.f = a; 396 return u.i >> 63; 397 } 398 399 INLINE float64 float64_is_zero(float64 a) 400 { 401 return fpclassify(a) == FP_ZERO; 402 } 403 404 INLINE float64 float64_scalbn(float64 a, int n) 405 { 406 return scalbn(a, n); 299 407 } 300 408 … … 369 477 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM ); 370 478 int floatx80_is_signaling_nan( floatx80 ); 479 int floatx80_is_nan( floatx80 ); 371 480 372 481 INLINE floatx80 floatx80_abs(floatx80 a) … … 379 488 return -a; 380 489 } 381 #endif 490 491 INLINE floatx80 floatx80_is_infinity(floatx80 a) 492 { 493 return fpclassify(a) == FP_INFINITE; 494 } 495 496 INLINE floatx80 floatx80_is_neg(floatx80 a) 497 { 498 floatx80u u; 499 u.f = a; 500 return u.i.high >> 15; 501 } 502 503 INLINE floatx80 floatx80_is_zero(floatx80 a) 504 { 505 return fpclassify(a) == FP_ZERO; 506 } 507 508 INLINE floatx80 floatx80_scalbn(floatx80 a, int n) 509 { 510 return scalbnl(a, n); 511 } 512 513 #endif -
trunk/src/recompiler_new/fpu/softfloat-specialize.h
r1 r18985 31 31 =============================================================================*/ 32 32 33 /*---------------------------------------------------------------------------- 34 | Underflow tininess-detection mode, statically initialized to default value. 35 | (The declaration in `softfloat.h' must match the `int8' type here.) 36 *----------------------------------------------------------------------------*/ 37 int8 float_detect_tininess = float_tininess_after_rounding; 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 38 39 39 /*---------------------------------------------------------------------------- … … 46 46 void float_raise( int8 flags STATUS_PARAM ) 47 47 { 48 49 48 STATUS(float_exception_flags) |= flags; 50 51 49 } 52 50 … … 62 60 | The pattern for a default generated single-precision NaN. 63 61 *----------------------------------------------------------------------------*/ 64 #define float32_default_nan 0xFFC00000 65 66 /*---------------------------------------------------------------------------- 67 | Returns 1 if the single-precision floating-point value `a' is a NaN; 68 | otherwise returns 0. 69 *----------------------------------------------------------------------------*/ 70 71 int float32_is_nan( float32 a ) 72 { 73 74 return ( 0xFF000000 < (bits32) ( a<<1 ) ); 75 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 76 87 } 77 88 … … 81 92 *----------------------------------------------------------------------------*/ 82 93 83 int float32_is_signaling_nan( float32 a ) 84 { 85 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 86 100 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 87 101 #endif 88 102 } 89 103 … … 99 113 100 114 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); 101 z.sign = a>>31;115 z.sign = float32_val(a)>>31; 102 116 z.low = 0; 103 z.high = ( (bits64) a)<<41;117 z.high = ( (bits64) float32_val(a) )<<41; 104 118 return z; 105 106 119 } 107 120 … … 113 126 static float32 commonNaNToFloat32( commonNaNT a ) 114 127 { 115 116 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); 117 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; 118 134 } 119 135 … … 127 143 { 128 144 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 145 bits32 av, bv, res; 146 147 if ( STATUS(default_nan_mode) ) 148 return float32_default_nan; 129 149 130 150 aIsNaN = float32_is_nan( a ); … … 132 152 bIsNaN = float32_is_nan( b ); 133 153 bIsSignalingNaN = float32_is_signaling_nan( b ); 134 a |= 0x00400000; 135 b |= 0x00400000; 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 136 163 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 137 164 if ( aIsSignalingNaN ) { 138 165 if ( bIsSignalingNaN ) goto returnLargerSignificand; 139 re turn bIsNaN ? b : a;166 res = bIsNaN ? bv : av; 140 167 } 141 168 else if ( aIsNaN ) { 142 if ( bIsSignalingNaN | ! bIsNaN ) return a; 169 if ( bIsSignalingNaN | ! bIsNaN ) 170 res = av; 171 else { 143 172 returnLargerSignificand: 144 if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b; 145 if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a; 146 return ( a < b ) ? a : b; 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 } 147 180 } 148 181 else { 149 re turn b;150 } 151 182 res = bv; 183 } 184 return make_float32(res); 152 185 } 153 186 … … 155 188 | The pattern for a default generated double-precision NaN. 156 189 *----------------------------------------------------------------------------*/ 157 #define float64_default_nan LIT64( 0xFFF8000000000000 ) 158 159 /*---------------------------------------------------------------------------- 160 | Returns 1 if the double-precision floating-point value `a' is a NaN; 161 | otherwise returns 0. 162 *----------------------------------------------------------------------------*/ 163 164 int float64_is_nan( float64 a ) 165 { 166 167 return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); 168 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 169 217 } 170 218 … … 174 222 *----------------------------------------------------------------------------*/ 175 223 176 int float64_is_signaling_nan( float64 a ) 177 { 178 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 179 230 return 180 231 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 181 232 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 182 233 #endif 183 234 } 184 235 … … 194 245 195 246 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 196 z.sign = a>>63;247 z.sign = float64_val(a)>>63; 197 248 z.low = 0; 198 z.high = a<<12;249 z.high = float64_val(a)<<12; 199 250 return z; 200 201 251 } 202 252 … … 208 258 static float64 commonNaNToFloat64( commonNaNT a ) 209 259 { 210 211 return 212 ( ( (bits64) a.sign )<<63 ) 213 | LIT64( 0x7FF8000000000000 ) 214 | ( a.high>>12 ); 215 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; 216 269 } 217 270 … … 225 278 { 226 279 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 280 bits64 av, bv, res; 281 282 if ( STATUS(default_nan_mode) ) 283 return float64_default_nan; 227 284 228 285 aIsNaN = float64_is_nan( a ); … … 230 287 bIsNaN = float64_is_nan( b ); 231 288 bIsSignalingNaN = float64_is_signaling_nan( b ); 232 a |= LIT64( 0x0008000000000000 ); 233 b |= LIT64( 0x0008000000000000 ); 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 234 298 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 235 299 if ( aIsSignalingNaN ) { 236 300 if ( bIsSignalingNaN ) goto returnLargerSignificand; 237 re turn bIsNaN ? b : a;301 res = bIsNaN ? bv : av; 238 302 } 239 303 else if ( aIsNaN ) { 240 if ( bIsSignalingNaN | ! bIsNaN ) return a; 304 if ( bIsSignalingNaN | ! bIsNaN ) 305 res = av; 306 else { 241 307 returnLargerSignificand: 242 if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b; 243 if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a; 244 return ( a < b ) ? a : b; 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 } 245 315 } 246 316 else { 247 re turn b;248 } 249 317 res = bv; 318 } 319 return make_float64(res); 250 320 } 251 321 … … 257 327 | respectively. 258 328 *----------------------------------------------------------------------------*/ 329 #if SNAN_BIT_IS_ONE 330 #define floatx80_default_nan_high 0x7FFF 331 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF ) 332 #else 259 333 #define floatx80_default_nan_high 0xFFFF 260 334 #define floatx80_default_nan_low LIT64( 0xC000000000000000 ) 335 #endif 261 336 262 337 /*---------------------------------------------------------------------------- 263 338 | Returns 1 if the extended double-precision floating-point value `a' is a 264 | NaN; otherwise returns 0.339 | quiet NaN; otherwise returns 0. 265 340 *----------------------------------------------------------------------------*/ 266 341 267 342 int floatx80_is_nan( floatx80 a ) 268 343 { 269 270 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 271 272 } 273 274 /*---------------------------------------------------------------------------- 275 | Returns 1 if the extended double-precision floating-point value `a' is a 276 | signaling NaN; otherwise returns 0. 277 *----------------------------------------------------------------------------*/ 278 279 int floatx80_is_signaling_nan( floatx80 a ) 280 { 344 #if SNAN_BIT_IS_ONE 281 345 bits64 aLow; 282 346 … … 286 350 && (bits64) ( aLow<<1 ) 287 351 && ( a.low == aLow ); 288 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 289 375 } 290 376 … … 302 388 z.sign = a.high>>15; 303 389 z.low = 0; 304 z.high = a.low <<1;390 z.high = a.low; 305 391 return z; 306 307 392 } 308 393 … … 316 401 floatx80 z; 317 402 318 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 403 if (a.high) 404 z.low = a.high; 405 else 406 z.low = floatx80_default_nan_low; 319 407 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 320 408 return z; 321 322 409 } 323 410 … … 331 418 { 332 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 } 333 426 334 427 aIsNaN = floatx80_is_nan( a ); … … 336 429 bIsNaN = floatx80_is_nan( b ); 337 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 338 435 a.low |= LIT64( 0xC000000000000000 ); 339 436 b.low |= LIT64( 0xC000000000000000 ); 437 #endif 340 438 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 341 439 if ( aIsSignalingNaN ) { … … 353 451 return b; 354 452 } 355 356 453 } 357 454 … … 364 461 | `low' values hold the most- and least-significant bits, respectively. 365 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 366 467 #define float128_default_nan_high LIT64( 0xFFFF800000000000 ) 367 468 #define float128_default_nan_low LIT64( 0x0000000000000000 ) 368 369 /*---------------------------------------------------------------------------- 370 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN; 371 | otherwise returns 0. 469 #endif 470 471 /*---------------------------------------------------------------------------- 472 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet 473 | NaN; otherwise returns 0. 372 474 *----------------------------------------------------------------------------*/ 373 475 374 476 int float128_is_nan( float128 a ) 375 477 { 376 478 #if SNAN_BIT_IS_ONE 479 return 480 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 481 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 482 #else 377 483 return 378 484 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 379 485 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 380 486 #endif 381 487 } 382 488 … … 388 494 int float128_is_signaling_nan( float128 a ) 389 495 { 390 496 #if SNAN_BIT_IS_ONE 497 return 498 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 499 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 500 #else 391 501 return 392 502 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 393 503 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 394 504 #endif 395 505 } 396 506 … … 409 519 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 410 520 return z; 411 412 521 } 413 522 … … 422 531 423 532 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 424 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF 800000000000 );533 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); 425 534 return z; 426 427 535 } 428 536 … … 436 544 { 437 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 } 438 552 439 553 aIsNaN = float128_is_nan( a ); … … 441 555 bIsNaN = float128_is_nan( b ); 442 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 443 561 a.high |= LIT64( 0x0000800000000000 ); 444 562 b.high |= LIT64( 0x0000800000000000 ); 563 #endif 445 564 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 446 565 if ( aIsSignalingNaN ) { … … 458 577 return b; 459 578 } 460 461 } 462 463 #endif 464 579 } 580 581 #endif -
trunk/src/recompiler_new/fpu/softfloat.c
r1 r18985 31 31 =============================================================================*/ 32 32 33 /* FIXME: Flush-To-Zero only effects results. Denormal inputs should also 34 be flushed to zero. */ 33 35 #include "softfloat.h" 34 36 … … 176 178 { 177 179 178 return a& 0x007FFFFF;180 return float32_val(a) & 0x007FFFFF; 179 181 180 182 } … … 187 189 { 188 190 189 return ( a>>23 ) & 0xFF;191 return ( float32_val(a)>>23 ) & 0xFF; 190 192 191 193 } … … 198 200 { 199 201 200 return a>>31;202 return float32_val(a)>>31; 201 203 202 204 } … … 234 236 { 235 237 236 return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig; 238 return make_float32( 239 ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig); 237 240 238 241 } … … 291 294 ) { 292 295 float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); 293 return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0);296 return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 )); 294 297 } 295 298 if ( zExp < 0 ) { 299 if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 ); 296 300 isTiny = 297 301 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 338 342 { 339 343 340 return a& LIT64( 0x000FFFFFFFFFFFFF );344 return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF ); 341 345 342 346 } … … 349 353 { 350 354 351 return ( a>>52 ) & 0x7FF;355 return ( float64_val(a)>>52 ) & 0x7FF; 352 356 353 357 } … … 360 364 { 361 365 362 return a>>63;366 return float64_val(a)>>63; 363 367 364 368 } … … 396 400 { 397 401 398 return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig; 402 return make_float64( 403 ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig); 399 404 400 405 } … … 453 458 ) { 454 459 float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); 455 return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0);460 return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 )); 456 461 } 457 462 if ( zExp < 0 ) { 463 if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 ); 458 464 isTiny = 459 465 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 634 640 } 635 641 if ( zExp <= 0 ) { 642 if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 ); 636 643 isTiny = 637 644 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 964 971 } 965 972 if ( zExp < 0 ) { 973 if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 ); 966 974 isTiny = 967 975 ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) … … 1051 1059 flag zSign; 1052 1060 1053 if ( a == 0 ) return 0;1061 if ( a == 0 ) return float32_zero; 1054 1062 if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); 1055 1063 zSign = ( a < 0 ); … … 1071 1079 bits64 zSig; 1072 1080 1073 if ( a == 0 ) return 0;1081 if ( a == 0 ) return float64_zero; 1074 1082 zSign = ( a < 0 ); 1075 1083 absA = zSign ? - a : a; … … 1145 1153 int8 shiftCount; 1146 1154 1147 if ( a == 0 ) return 0;1155 if ( a == 0 ) return float32_zero; 1148 1156 zSign = ( a < 0 ); 1149 1157 absA = zSign ? - a : a; … … 1165 1173 } 1166 1174 1175 float32 uint64_to_float32( uint64 a STATUS_PARAM ) 1176 { 1177 int8 shiftCount; 1178 1179 if ( a == 0 ) return float32_zero; 1180 shiftCount = countLeadingZeros64( a ) - 40; 1181 if ( 0 <= shiftCount ) { 1182 return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount ); 1183 } 1184 else { 1185 shiftCount += 7; 1186 if ( shiftCount < 0 ) { 1187 shift64RightJamming( a, - shiftCount, &a ); 1188 } 1189 else { 1190 a <<= shiftCount; 1191 } 1192 return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR ); 1193 } 1194 } 1195 1167 1196 /*---------------------------------------------------------------------------- 1168 1197 | Returns the result of converting the 64-bit two's complement integer `a' … … 1175 1204 flag zSign; 1176 1205 1177 if ( a == 0 ) return 0;1206 if ( a == 0 ) return float64_zero; 1178 1207 if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) { 1179 1208 return packFloat64( 1, 0x43E, 0 ); … … 1181 1210 zSign = ( a < 0 ); 1182 1211 return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR ); 1212 1213 } 1214 1215 float64 uint64_to_float64( uint64 a STATUS_PARAM ) 1216 { 1217 if ( a == 0 ) return float64_zero; 1218 return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR ); 1183 1219 1184 1220 } … … 1298 1334 shiftCount = aExp - 0x9E; 1299 1335 if ( 0 <= shiftCount ) { 1300 if ( a!= 0xCF000000 ) {1336 if ( float32_val(a) != 0xCF000000 ) { 1301 1337 float_raise( float_flag_invalid STATUS_VAR); 1302 1338 if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; … … 1377 1413 shiftCount = aExp - 0xBE; 1378 1414 if ( 0 <= shiftCount ) { 1379 if ( a!= 0xDF000000 ) {1415 if ( float32_val(a) != 0xDF000000 ) { 1380 1416 float_raise( float_flag_invalid STATUS_VAR); 1381 1417 if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { … … 1508 1544 bits32 lastBitMask, roundBitsMask; 1509 1545 int8 roundingMode; 1510 float32 z;1546 bits32 z; 1511 1547 1512 1548 aExp = extractFloat32Exp( a ); … … 1518 1554 } 1519 1555 if ( aExp <= 0x7E ) { 1520 if ( (bits32) ( a<<1 ) == 0 ) return a;1556 if ( (bits32) ( float32_val(a)<<1 ) == 0 ) return a; 1521 1557 STATUS(float_exception_flags) |= float_flag_inexact; 1522 1558 aSign = extractFloat32Sign( a ); … … 1528 1564 break; 1529 1565 case float_round_down: 1530 return aSign ? 0xBF800000 : 0;1566 return make_float32(aSign ? 0xBF800000 : 0); 1531 1567 case float_round_up: 1532 return aSign ? 0x80000000 : 0x3F800000;1568 return make_float32(aSign ? 0x80000000 : 0x3F800000); 1533 1569 } 1534 1570 return packFloat32( aSign, 0, 0 ); … … 1537 1573 lastBitMask <<= 0x96 - aExp; 1538 1574 roundBitsMask = lastBitMask - 1; 1539 z = a;1575 z = float32_val(a); 1540 1576 roundingMode = STATUS(float_rounding_mode); 1541 1577 if ( roundingMode == float_round_nearest_even ) { … … 1544 1580 } 1545 1581 else if ( roundingMode != float_round_to_zero ) { 1546 if ( extractFloat32Sign( z) ^ ( roundingMode == float_round_up ) ) {1582 if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) { 1547 1583 z += roundBitsMask; 1548 1584 } 1549 1585 } 1550 1586 z &= ~ roundBitsMask; 1551 if ( z != a) STATUS(float_exception_flags) |= float_flag_inexact;1552 return z;1587 if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact; 1588 return make_float32(z); 1553 1589 1554 1590 } … … 1608 1644 return a; 1609 1645 } 1610 if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); 1646 if ( aExp == 0 ) { 1647 if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 ); 1648 return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); 1649 } 1611 1650 zSig = 0x40000000 + aSig + bSig; 1612 1651 zExp = aExp; … … 1981 2020 aSign = extractFloat32Sign( a ); 1982 2021 if ( aExp == 0xFF ) { 1983 if ( aSig ) return propagateFloat32NaN( a, 0STATUS_VAR );2022 if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR ); 1984 2023 if ( ! aSign ) return a; 1985 2024 float_raise( float_flag_invalid STATUS_VAR); … … 1992 2031 } 1993 2032 if ( aExp == 0 ) { 1994 if ( aSig == 0 ) return 0;2033 if ( aSig == 0 ) return float32_zero; 1995 2034 normalizeFloat32Subnormal( aSig, &aExp, &aSig ); 1996 2035 } … … 2019 2058 2020 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 Binary 2062 | 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 } 2105 2106 /*---------------------------------------------------------------------------- 2021 2107 | Returns 1 if the single-precision floating-point value `a' is equal to 2022 2108 | the corresponding value `b', and 0 otherwise. The comparison is performed … … 2035 2121 return 0; 2036 2122 } 2037 return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); 2123 return ( float32_val(a) == float32_val(b) ) || 2124 ( (bits32) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 ); 2038 2125 2039 2126 } … … 2049 2136 { 2050 2137 flag aSign, bSign; 2138 bits32 av, bv; 2051 2139 2052 2140 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) … … 2058 2146 aSign = extractFloat32Sign( a ); 2059 2147 bSign = extractFloat32Sign( b ); 2060 if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); 2061 return ( a == b ) || ( aSign ^ ( a < b ) ); 2148 av = float32_val(a); 2149 bv = float32_val(b); 2150 if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 ); 2151 return ( av == bv ) || ( aSign ^ ( av < bv ) ); 2062 2152 2063 2153 } … … 2072 2162 { 2073 2163 flag aSign, bSign; 2164 bits32 av, bv; 2074 2165 2075 2166 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) … … 2081 2172 aSign = extractFloat32Sign( a ); 2082 2173 bSign = extractFloat32Sign( b ); 2083 if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); 2084 return ( a != b ) && ( aSign ^ ( a < b ) ); 2174 av = float32_val(a); 2175 bv = float32_val(b); 2176 if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 ); 2177 return ( av != bv ) && ( aSign ^ ( av < bv ) ); 2085 2178 2086 2179 } … … 2095 2188 int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) 2096 2189 { 2190 bits32 av, bv; 2097 2191 2098 2192 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) … … 2102 2196 return 0; 2103 2197 } 2104 return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); 2198 av = float32_val(a); 2199 bv = float32_val(b); 2200 return ( av == bv ) || ( (bits32) ( ( av | bv )<<1 ) == 0 ); 2105 2201 2106 2202 } … … 2116 2212 { 2117 2213 flag aSign, bSign; 2214 bits32 av, bv; 2118 2215 2119 2216 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) … … 2127 2224 aSign = extractFloat32Sign( a ); 2128 2225 bSign = extractFloat32Sign( b ); 2129 if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); 2130 return ( a == b ) || ( aSign ^ ( a < b ) ); 2226 av = float32_val(a); 2227 bv = float32_val(b); 2228 if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 ); 2229 return ( av == bv ) || ( aSign ^ ( av < bv ) ); 2131 2230 2132 2231 } … … 2142 2241 { 2143 2242 flag aSign, bSign; 2243 bits32 av, bv; 2144 2244 2145 2245 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) … … 2153 2253 aSign = extractFloat32Sign( a ); 2154 2254 bSign = extractFloat32Sign( b ); 2155 if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); 2156 return ( a != b ) && ( aSign ^ ( a < b ) ); 2255 av = float32_val(a); 2256 bv = float32_val(b); 2257 if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 ); 2258 return ( av != bv ) && ( aSign ^ ( av < bv ) ); 2157 2259 2158 2260 } … … 2297 2399 if ( 0 <= shiftCount ) { 2298 2400 if ( 0x43E <= aExp ) { 2299 if ( a!= LIT64( 0xC3E0000000000000 ) ) {2401 if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) { 2300 2402 float_raise( float_flag_invalid STATUS_VAR); 2301 2403 if ( ! aSign … … 2437 2539 bits64 lastBitMask, roundBitsMask; 2438 2540 int8 roundingMode; 2439 float64 z;2541 bits64 z; 2440 2542 2441 2543 aExp = extractFloat64Exp( a ); … … 2447 2549 } 2448 2550 if ( aExp < 0x3FF ) { 2449 if ( (bits64) ( a<<1 ) == 0 ) return a;2551 if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a; 2450 2552 STATUS(float_exception_flags) |= float_flag_inexact; 2451 2553 aSign = extractFloat64Sign( a ); … … 2457 2559 break; 2458 2560 case float_round_down: 2459 return aSign ? LIT64( 0xBFF0000000000000 ) : 0;2561 return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0); 2460 2562 case float_round_up: 2461 return 2462 aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ) ;2563 return make_float64( 2564 aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 )); 2463 2565 } 2464 2566 return packFloat64( aSign, 0, 0 ); … … 2467 2569 lastBitMask <<= 0x433 - aExp; 2468 2570 roundBitsMask = lastBitMask - 1; 2469 z = a;2571 z = float64_val(a); 2470 2572 roundingMode = STATUS(float_rounding_mode); 2471 2573 if ( roundingMode == float_round_nearest_even ) { … … 2474 2576 } 2475 2577 else if ( roundingMode != float_round_to_zero ) { 2476 if ( extractFloat64Sign( z) ^ ( roundingMode == float_round_up ) ) {2578 if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) { 2477 2579 z += roundBitsMask; 2478 2580 } 2479 2581 } 2480 2582 z &= ~ roundBitsMask; 2481 if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact; 2482 return z; 2583 if ( z != float64_val(a) ) 2584 STATUS(float_exception_flags) |= float_flag_inexact; 2585 return make_float64(z); 2483 2586 2484 2587 } … … 2549 2652 return a; 2550 2653 } 2551 if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); 2654 if ( aExp == 0 ) { 2655 if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 ); 2656 return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); 2657 } 2552 2658 zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; 2553 2659 zExp = aExp; … … 2924 3030 } 2925 3031 if ( aExp == 0 ) { 2926 if ( aSig == 0 ) return 0;3032 if ( aSig == 0 ) return float64_zero; 2927 3033 normalizeFloat64Subnormal( aSig, &aExp, &aSig ); 2928 3034 } … … 2948 3054 2949 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 Binary 3058 | 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 } 3100 3101 /*---------------------------------------------------------------------------- 2950 3102 | Returns 1 if the double-precision floating-point value `a' is equal to the 2951 3103 | corresponding value `b', and 0 otherwise. The comparison is performed … … 2955 3107 int float64_eq( float64 a, float64 b STATUS_PARAM ) 2956 3108 { 3109 bits64 av, bv; 2957 3110 2958 3111 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) … … 2964 3117 return 0; 2965 3118 } 2966 return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); 3119 av = float64_val(a); 3120 bv = float64_val(b); 3121 return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 ); 2967 3122 2968 3123 } … … 2978 3133 { 2979 3134 flag aSign, bSign; 3135 bits64 av, bv; 2980 3136 2981 3137 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) … … 2987 3143 aSign = extractFloat64Sign( a ); 2988 3144 bSign = extractFloat64Sign( b ); 2989 if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); 2990 return ( a == b ) || ( aSign ^ ( a < b ) ); 3145 av = float64_val(a); 3146 bv = float64_val(b); 3147 if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 ); 3148 return ( av == bv ) || ( aSign ^ ( av < bv ) ); 2991 3149 2992 3150 } … … 3001 3159 { 3002 3160 flag aSign, bSign; 3161 bits64 av, bv; 3003 3162 3004 3163 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) … … 3010 3169 aSign = extractFloat64Sign( a ); 3011 3170 bSign = extractFloat64Sign( b ); 3012 if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); 3013 return ( a != b ) && ( aSign ^ ( a < b ) ); 3171 av = float64_val(a); 3172 bv = float64_val(b); 3173 if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 ); 3174 return ( av != bv ) && ( aSign ^ ( av < bv ) ); 3014 3175 3015 3176 } … … 3024 3185 int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) 3025 3186 { 3187 bits64 av, bv; 3026 3188 3027 3189 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) … … 3031 3193 return 0; 3032 3194 } 3033 return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); 3195 av = float64_val(a); 3196 bv = float64_val(b); 3197 return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 ); 3034 3198 3035 3199 } … … 3045 3209 { 3046 3210 flag aSign, bSign; 3211 bits64 av, bv; 3047 3212 3048 3213 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) … … 3056 3221 aSign = extractFloat64Sign( a ); 3057 3222 bSign = extractFloat64Sign( b ); 3058 if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); 3059 return ( a == b ) || ( aSign ^ ( a < b ) ); 3223 av = float64_val(a); 3224 bv = float64_val(b); 3225 if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 ); 3226 return ( av == bv ) || ( aSign ^ ( av < bv ) ); 3060 3227 3061 3228 } … … 3071 3238 { 3072 3239 flag aSign, bSign; 3240 bits64 av, bv; 3073 3241 3074 3242 if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) … … 3082 3250 aSign = extractFloat64Sign( a ); 3083 3251 bSign = extractFloat64Sign( b ); 3084 if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); 3085 return ( a != b ) && ( aSign ^ ( a < b ) ); 3252 av = float64_val(a); 3253 bv = float64_val(b); 3254 if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 ); 3255 return ( av != bv ) && ( aSign ^ ( av < bv ) ); 3086 3256 3087 3257 } … … 4533 4703 } 4534 4704 add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); 4535 if ( aExp == 0 ) return packFloat128( zSign, 0, 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 } 4536 4709 zSig2 = 0; 4537 4710 zSig0 |= LIT64( 0x0002000000000000 ); … … 4923 5096 } while ( 0 <= (sbits64) aSig0 ); 4924 5097 add128( 4925 aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );5098 aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); 4926 5099 if ( ( sigMean0 < 0 ) 4927 5100 || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { … … 5283 5456 } 5284 5457 5458 /* FIXME: This looks broken. */ 5459 uint64_t float64_to_uint64 (float64 a STATUS_PARAM) 5460 { 5461 int64_t v; 5462 5463 v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); 5464 v += float64_val(a); 5465 v = float64_to_int64(make_float64(v) STATUS_VAR); 5466 5467 return v - INT64_MIN; 5468 } 5469 5470 uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) 5471 { 5472 int64_t v; 5473 5474 v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR)); 5475 v += float64_val(a); 5476 v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR); 5477 5478 return v - INT64_MIN; 5479 } 5480 5285 5481 #define COMPARE(s, nan_exp) \ 5286 5482 INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ … … 5288 5484 { \ 5289 5485 flag aSign, bSign; \ 5486 bits ## s av, bv; \ 5290 5487 \ 5291 5488 if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \ … … 5302 5499 aSign = extractFloat ## s ## Sign( a ); \ 5303 5500 bSign = extractFloat ## s ## Sign( b ); \ 5501 av = float ## s ## _val(a); \ 5502 bv = float ## s ## _val(b); \ 5304 5503 if ( aSign != bSign ) { \ 5305 if ( (bits ## s) ( ( a | b )<<1 ) == 0 ) {\5504 if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) { \ 5306 5505 /* zero case */ \ 5307 5506 return float_relation_equal; \ … … 5310 5509 } \ 5311 5510 } else { \ 5312 if (a == b) {\5511 if (av == bv) { \ 5313 5512 return float_relation_equal; \ 5314 5513 } else { \ 5315 return 1 - 2 * (aSign ^ ( a < b ));\5514 return 1 - 2 * (aSign ^ ( av < bv )); \ 5316 5515 } \ 5317 5516 } \ … … 5330 5529 COMPARE(32, 0xff) 5331 5530 COMPARE(64, 0x7ff) 5531 5532 INLINE int float128_compare_internal( float128 a, float128 b, 5533 int is_quiet STATUS_PARAM ) 5534 { 5535 flag aSign, bSign; 5536 5537 if (( ( extractFloat128Exp( a ) == 0x7fff ) && 5538 ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) || 5539 ( ( extractFloat128Exp( b ) == 0x7fff ) && 5540 ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) { 5541 if (!is_quiet || 5542 float128_is_signaling_nan( a ) || 5543 float128_is_signaling_nan( b ) ) { 5544 float_raise( float_flag_invalid STATUS_VAR); 5545 } 5546 return float_relation_unordered; 5547 } 5548 aSign = extractFloat128Sign( a ); 5549 bSign = extractFloat128Sign( b ); 5550 if ( aSign != bSign ) { 5551 if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) { 5552 /* zero case */ 5553 return float_relation_equal; 5554 } else { 5555 return 1 - (2 * aSign); 5556 } 5557 } else { 5558 if (a.low == b.low && a.high == b.high) { 5559 return float_relation_equal; 5560 } else { 5561 return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) )); 5562 } 5563 } 5564 } 5565 5566 int float128_compare( float128 a, float128 b STATUS_PARAM ) 5567 { 5568 return float128_compare_internal(a, b, 0 STATUS_VAR); 5569 } 5570 5571 int float128_compare_quiet( float128 a, float128 b STATUS_PARAM ) 5572 { 5573 return float128_compare_internal(a, b, 1 STATUS_VAR); 5574 } 5575 5576 /* Multiply A by 2 raised to the power N. */ 5577 float32 float32_scalbn( float32 a, int n STATUS_PARAM ) 5578 { 5579 flag aSign; 5580 int16 aExp; 5581 bits32 aSig; 5582 5583 aSig = extractFloat32Frac( a ); 5584 aExp = extractFloat32Exp( a ); 5585 aSign = extractFloat32Sign( a ); 5586 5587 if ( aExp == 0xFF ) { 5588 return a; 5589 } 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 ); 5598 } 5599 5600 float64 float64_scalbn( float64 a, int n STATUS_PARAM ) 5601 { 5602 flag aSign; 5603 int16 aExp; 5604 bits64 aSig; 5605 5606 aSig = extractFloat64Frac( a ); 5607 aExp = extractFloat64Exp( a ); 5608 aSign = extractFloat64Sign( a ); 5609 5610 if ( aExp == 0x7FF ) { 5611 return a; 5612 } 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 ); 5621 } 5622 5623 #ifdef FLOATX80 5624 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) 5625 { 5626 flag aSign; 5627 int16 aExp; 5628 bits64 aSig; 5629 5630 aSig = extractFloatx80Frac( a ); 5631 aExp = extractFloatx80Exp( a ); 5632 aSign = extractFloatx80Sign( a ); 5633 5634 if ( aExp == 0x7FF ) { 5635 return a; 5636 } 5637 if (aExp == 0 && aSig == 0) 5638 return a; 5639 5640 aExp += n; 5641 return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision), 5642 aSign, aExp, aSig, 0 STATUS_VAR ); 5643 } 5644 #endif 5645 5646 #ifdef FLOAT128 5647 float128 float128_scalbn( float128 a, int n STATUS_PARAM ) 5648 { 5649 flag aSign; 5650 int32 aExp; 5651 bits64 aSig0, aSig1; 5652 5653 aSig1 = extractFloat128Frac1( a ); 5654 aSig0 = extractFloat128Frac0( a ); 5655 aExp = extractFloat128Exp( a ); 5656 aSign = extractFloat128Sign( a ); 5657 if ( aExp == 0x7FFF ) { 5658 return a; 5659 } 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 ); 5668 5669 } 5670 #endif -
trunk/src/recompiler_new/fpu/softfloat.h
r13384 r18985 36 36 #include <VBox/types.h> 37 37 #endif 38 39 #if defined(HOST_SOLARIS) && defined(NEEDS_LIBSUNMATH) 40 #include <sunmath.h> 41 #endif 42 43 #include <inttypes.h> 38 44 #include "config.h" 39 45 … … 49 55 typedef uint8_t uint8; 50 56 typedef int8_t int8; 57 #ifndef _AIX 51 58 typedef int uint16; 52 59 typedef int int16; 60 #endif 53 61 typedef unsigned int uint32; 54 62 typedef signed int int32; … … 72 80 73 81 #define LIT64( a ) a##LL 74 #ifdef _MSC_VER75 #define INLINE76 #else77 82 #define INLINE static inline 78 #endif79 83 80 84 /*---------------------------------------------------------------------------- … … 95 99 #endif 96 100 #endif /* !CONFIG_SOFTFLOAT */ 101 97 102 #if defined(VBOX) && (!defined(FLOATX80) || defined(CONFIG_SOFTFLOAT)) 98 103 # error misconfigured … … 117 122 | Software IEC/IEEE floating-point types. 118 123 *----------------------------------------------------------------------------*/ 124 /* Use structures for soft-float types. This prevents accidentally mixing 125 them with native int/float types. A sufficiently clever compiler and 126 sane ABI should be able to see though these structs. However 127 x86/gcc 3.x seems to struggle a bit, so leave them disabled by default. */ 128 //#define USE_SOFTFLOAT_STRUCT_TYPES 129 #ifdef USE_SOFTFLOAT_STRUCT_TYPES 130 typedef struct { 131 uint32_t v; 132 } float32; 133 /* The cast ensures an error if the wrong type is passed. */ 134 #define float32_val(x) (((float32)(x)).v) 135 #define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; }) 136 typedef struct { 137 uint64_t v; 138 } float64; 139 #define float64_val(x) (((float64)(x)).v) 140 #define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; }) 141 #else 119 142 typedef uint32_t float32; 120 143 typedef uint64_t float64; 144 #define float32_val(x) (x) 145 #define float64_val(x) (x) 146 #define make_float32(x) (x) 147 #define make_float64(x) (x) 148 #endif 121 149 #ifdef FLOATX80 122 150 typedef struct { … … 171 199 signed char floatx80_rounding_precision; 172 200 #endif 201 flag flush_to_zero; 202 flag default_nan_mode; 173 203 } float_status; 174 204 175 205 void set_float_rounding_mode(int val STATUS_PARAM); 176 206 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 } 177 215 INLINE int get_float_exception_flags(float_status *status) 178 216 { … … 203 241 #endif 204 242 float32 int64_to_float32( int64_t STATUS_PARAM ); 243 float32 uint64_to_float32( uint64_t STATUS_PARAM ); 205 244 float64 int64_to_float64( int64_t STATUS_PARAM ); 245 float64 uint64_to_float64( uint64_t STATUS_PARAM ); 206 246 #ifdef FLOATX80 207 247 floatx80 int64_to_floatx80( int64_t STATUS_PARAM ); … … 238 278 float32 float32_rem( float32, float32 STATUS_PARAM ); 239 279 float32 float32_sqrt( float32 STATUS_PARAM ); 280 float32 float32_log2( float32 STATUS_PARAM ); 240 281 int float32_eq( float32, float32 STATUS_PARAM ); 241 282 int float32_le( float32, float32 STATUS_PARAM ); … … 246 287 int float32_compare( float32, float32 STATUS_PARAM ); 247 288 int float32_compare_quiet( float32, float32 STATUS_PARAM ); 289 int float32_is_nan( float32 ); 248 290 int float32_is_signaling_nan( float32 ); 249 int float64_is_nan( float64 a);291 float32 float32_scalbn( float32, int STATUS_PARAM ); 250 292 251 293 INLINE float32 float32_abs(float32 a) 252 294 { 253 return a & 0x7fffffff;295 return make_float32(float32_val(a) & 0x7fffffff); 254 296 } 255 297 256 298 INLINE float32 float32_chs(float32 a) 257 299 { 258 return a ^ 0x80000000; 259 } 300 return make_float32(float32_val(a) ^ 0x80000000); 301 } 302 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 #define float32_zero make_float32(0) 319 #define float32_one make_float32(0x3f800000) 260 320 261 321 /*---------------------------------------------------------------------------- … … 268 328 int64_t float64_to_int64( float64 STATUS_PARAM ); 269 329 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM ); 330 uint64_t float64_to_uint64 (float64 a STATUS_PARAM); 331 uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM); 270 332 float32 float64_to_float32( float64 STATUS_PARAM ); 271 333 #ifdef FLOATX80 … … 287 349 float64 float64_rem( float64, float64 STATUS_PARAM ); 288 350 float64 float64_sqrt( float64 STATUS_PARAM ); 351 float64 float64_log2( float64 STATUS_PARAM ); 289 352 int float64_eq( float64, float64 STATUS_PARAM ); 290 353 int float64_le( float64, float64 STATUS_PARAM ); … … 295 358 int float64_compare( float64, float64 STATUS_PARAM ); 296 359 int float64_compare_quiet( float64, float64 STATUS_PARAM ); 360 int float64_is_nan( float64 a ); 297 361 int float64_is_signaling_nan( float64 ); 362 float64 float64_scalbn( float64, int STATUS_PARAM ); 298 363 299 364 INLINE float64 float64_abs(float64 a) 300 365 { 301 return a & 0x7fffffffffffffffLL;366 return make_float64(float64_val(a) & 0x7fffffffffffffffLL); 302 367 } 303 368 304 369 INLINE float64 float64_chs(float64 a) 305 370 { 306 return a ^ 0x8000000000000000LL; 307 } 371 return make_float64(float64_val(a) ^ 0x8000000000000000LL); 372 } 373 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 #define float64_zero make_float64(0) 390 #define float64_one make_float64(0x3ff0000000000000LL) 308 391 309 392 #ifdef FLOATX80 … … 338 421 int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM ); 339 422 int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM ); 423 int floatx80_is_nan( floatx80 ); 340 424 int floatx80_is_signaling_nan( floatx80 ); 425 floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM ); 341 426 342 427 INLINE floatx80 floatx80_abs(floatx80 a) … … 350 435 a.high ^= 0x8000; 351 436 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; 352 452 } 353 453 … … 385 485 int float128_le_quiet( float128, float128 STATUS_PARAM ); 386 486 int float128_lt_quiet( float128, float128 STATUS_PARAM ); 487 int float128_compare( float128, float128 STATUS_PARAM ); 488 int float128_compare_quiet( float128, float128 STATUS_PARAM ); 489 int float128_is_nan( float128 ); 387 490 int float128_is_signaling_nan( float128 ); 491 float128 float128_scalbn( float128, int STATUS_PARAM ); 388 492 389 493 INLINE float128 float128_abs(float128 a) … … 399 503 } 400 504 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 401 520 #endif 402 521
Note:
See TracChangeset
for help on using the changeset viewer.