softfloat-native.c revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/* Native implementation of soft float functions. Only a single status
context is supported */
#include "softfloat.h"
#include <math.h>
{
/* nothing to do */
#else
#endif
}
#ifdef FLOATX80
{
}
#endif
#endif
#if defined(__powerpc__)
/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
double qemu_rint(double x)
{
double y = 4503599627370496.0;
if (fabs(x) >= y)
return x;
if (x < 0)
y = -y;
y = (x + y) - y;
if (y == 0.0)
y = copysign(y, x);
return y;
}
#endif
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return (float32)v;
}
{
return (float64)v;
}
#ifdef FLOATX80
{
return (floatx80)v;
}
#endif
{
return (float32)v;
}
{
return (float64)v;
}
#ifdef FLOATX80
{
return (floatx80)v;
}
#endif
/* XXX: this code implements the x86 behaviour, not the IEEE one. */
#if HOST_LONG_BITS == 32
static inline int long_to_int32(long a)
{
return a;
}
#else
static inline int long_to_int32(long a)
{
if (a != (int32_t)a)
a = 0x80000000;
return a;
}
#endif
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return long_to_int32(lrintf(a));
}
{
return (int)a;
}
{
return llrintf(a);
}
{
return (int64_t)a;
}
{
return a;
}
#ifdef FLOATX80
{
return a;
}
#endif
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return rintf(a);
}
{
return remainderf(a, b);
}
{
return sqrtf(a);
}
{
if (a < b) {
return -1;
} else if (a == b) {
return 0;
} else if (a > b) {
return 1;
} else {
return 2;
}
}
{
if (isless(a, b)) {
return -1;
} else if (a == b) {
return 0;
} else if (isgreater(a, b)) {
return 1;
} else {
return 2;
}
}
{
float32u u;
uint32_t a;
u.f = a1;
a = u.i;
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
}
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return long_to_int32(lrint(a));
}
{
return (int)a;
}
{
return llrint(a);
}
{
return (int64_t)a;
}
{
return a;
}
#ifdef FLOATX80
{
return a;
}
#endif
#ifdef FLOAT128
{
return a;
}
#endif
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return trunc(a);
}
{
#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
}
{
return remainder(a, b);
}
{
return sqrt(a);
}
{
if (a < b) {
return -1;
} else if (a == b) {
return 0;
} else if (a > b) {
return 1;
} else {
return 2;
}
}
{
if (isless(a, b)) {
return -1;
} else if (a == b) {
return 0;
} else if (isgreater(a, b)) {
return 1;
} else {
return 2;
}
}
{
float64u u;
uint64_t a;
u.f = a1;
a = u.i;
return
( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
&& ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
}
{
float64u u;
uint64_t a;
u.f = a1;
a = u.i;
}
#ifdef FLOATX80
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return long_to_int32(lrintl(a));
}
{
return (int)a;
}
{
return llrintl(a);
}
{
return (int64_t)a;
}
{
return a;
}
{
return a;
}
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
{
return rintl(a);
}
{
return remainderl(a, b);
}
{
return sqrtl(a);
}
{
if (a < b) {
return -1;
} else if (a == b) {
return 0;
} else if (a > b) {
return 1;
} else {
return 2;
}
}
{
if (isless(a, b)) {
return -1;
} else if (a == b) {
return 0;
} else if (isgreater(a, b)) {
return 1;
} else {
return 2;
}
}
{
floatx80u u;
u.f = a1;
}
#endif