context is supported */
#include "softfloat.h"
#include <math.h>
+#if defined(CONFIG_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(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) || \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
fpsetround(val);
-#elif defined(__arm__)
- /* nothing to do */
#else
fesetround(val);
#endif
}
#endif
-#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
+#if defined(CONFIG_BSD) || \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
#define lrint(d) ((int32_t)rint(d))
#define llrint(d) ((int64_t)rint(d))
#define lrintf(f) ((int32_t)rint(f))
#define sqrtf(f) ((float)sqrt(f))
#define remainderf(fa, fb) ((float)remainder(fa, fb))
#define rintf(f) ((float)rint(f))
-#if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
+#if !defined(__sparc__) && \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
extern long double rintl(long double);
extern long double scalbnl(long double, int);
#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)
return x;
- if (x < 0)
+ if (x < 0)
y = -y;
y = (x + y) - y;
if (y == 0.0)
#else
static inline int long_to_int32(long a)
{
- if (a != (int32_t)a)
+ if (a != (int32_t)a)
a = 0x80000000;
return a;
}
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)
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.
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision operations.
*----------------------------------------------------------------------------*/
-#if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
+#if defined(__sun__) && \
+ (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10)
static inline float64 trunc(float64 x)
{
return x < 0 ? -floor(-x) : floor(x);
float64 float64_round_to_int( float64 a STATUS_PARAM )
{
-#if defined(__arm__)
- switch(STATUS(float_rounding_mode)) {
- default:
- case float_round_nearest_even:
- asm("rndd %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_down:
- asm("rnddm %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_up:
- asm("rnddp %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_to_zero:
- asm("rnddz %0, %1" : "=f" (a) : "f"(a));
- break;
- }
-#else
return rint(a);
-#endif
}
float64 float64_rem( float64 a, float64 b 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)
u.f = a1;
a = u.i;
- return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
+ return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) );
}
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;