diff options
Diffstat (limited to 'fpu/softfloat-native.c')
-rw-r--r-- | fpu/softfloat-native.c | 84 |
1 files changed, 55 insertions, 29 deletions
diff --git a/fpu/softfloat-native.c b/fpu/softfloat-native.c index e58551f..2af07a3 100644 --- a/fpu/softfloat-native.c +++ b/fpu/softfloat-native.c @@ -2,11 +2,15 @@ context is supported */ #include "softfloat.h" #include <math.h> +#if defined(HOST_SOLARIS) +#include <fenv.h> +#endif void set_float_rounding_mode(int val STATUS_PARAM) { STATUS(float_rounding_mode) = val; -#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10) +#if defined(HOST_BSD) && !defined(__APPLE__) || \ + (defined(HOST_SOLARIS) && HOST_SOLARIS < 10) fpsetround(val); #elif defined(__arm__) /* nothing to do */ @@ -22,7 +26,7 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM) } #endif -#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10) +#if defined(HOST_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10) #define lrint(d) ((int32_t)rint(d)) #define llrint(d) ((int64_t)rint(d)) #define lrintf(f) ((int32_t)rint(f)) @@ -51,10 +55,10 @@ ldexpl(long double x, int n) { #endif #endif -#if defined(__powerpc__) +#if defined(_ARCH_PPC) /* correct (but slow) PowerPC rint() (glibc version is incorrect) */ -double qemu_rint(double x) +static double qemu_rint(double x) { double y = 4503599627370496.0; if (fabs(x) >= y) @@ -220,25 +224,25 @@ float32 float32_sqrt( float32 a STATUS_PARAM) int float32_compare( float32 a, float32 b STATUS_PARAM ) { if (a < b) { - return -1; + return float_relation_less; } else if (a == b) { - return 0; + return float_relation_equal; } else if (a > b) { - return 1; + return float_relation_greater; } else { - return 2; + return float_relation_unordered; } } int float32_compare_quiet( float32 a, float32 b STATUS_PARAM ) { if (isless(a, b)) { - return -1; + return float_relation_less; } else if (a == b) { - return 0; + return float_relation_equal; } else if (isgreater(a, b)) { - return 1; + return float_relation_greater; } else { - return 2; + return float_relation_unordered; } } int float32_is_signaling_nan( float32 a1) @@ -250,6 +254,15 @@ int float32_is_signaling_nan( float32 a1) return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); } +int float32_is_nan( float32 a1 ) +{ + float32u u; + uint64_t a; + u.f = a1; + a = u.i; + return ( 0xFF800000 < ( a<<1 ) ); +} + /*---------------------------------------------------------------------------- | Software IEC/IEEE double-precision conversion routines. *----------------------------------------------------------------------------*/ @@ -382,25 +395,25 @@ float64 float64_sqrt( float64 a STATUS_PARAM) int float64_compare( float64 a, float64 b STATUS_PARAM ) { if (a < b) { - return -1; + return float_relation_less; } else if (a == b) { - return 0; + return float_relation_equal; } else if (a > b) { - return 1; + return float_relation_greater; } else { - return 2; + return float_relation_unordered; } } int float64_compare_quiet( float64 a, float64 b STATUS_PARAM ) { if (isless(a, b)) { - return -1; + return float_relation_less; } else if (a == b) { - return 0; + return float_relation_equal; } else if (isgreater(a, b)) { - return 1; + return float_relation_greater; } else { - return 2; + return float_relation_unordered; } } int float64_is_signaling_nan( float64 a1) @@ -422,7 +435,7 @@ int float64_is_nan( float64 a1 ) u.f = a1; a = u.i; - return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); + return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) ); } @@ -474,30 +487,43 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM) int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM ) { if (a < b) { - return -1; + return float_relation_less; } else if (a == b) { - return 0; + return float_relation_equal; } else if (a > b) { - return 1; + return float_relation_greater; } else { - return 2; + return float_relation_unordered; } } int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM ) { if (isless(a, b)) { - return -1; + return float_relation_less; } else if (a == b) { - return 0; + return float_relation_equal; } else if (isgreater(a, b)) { - return 1; + return float_relation_greater; } else { - return 2; + return float_relation_unordered; } } int floatx80_is_signaling_nan( floatx80 a1) { floatx80u u; + uint64_t aLow; + u.f = a1; + + aLow = u.i.low & ~ LIT64( 0x4000000000000000 ); + return + ( ( u.i.high & 0x7FFF ) == 0x7FFF ) + && (bits64) ( aLow<<1 ) + && ( u.i.low == aLow ); +} + +int floatx80_is_nan( floatx80 a1 ) +{ + floatx80u u; u.f = a1; return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 ); } |