#define EXCESS 126L
#define SIGNBIT 0x80000000L
#define HIDDEN (1L << 23L)
#define SIGN(fp) ((fp) & SIGNBIT)
#define EXP(fp) (((fp) >> 23L) & 0xFF)
#define MANT(fp) (((fp) & 0x7FFFFFL) | HIDDEN)
#define PACK(s,e,m) ((s) | ((e) << 23L) | (m))
#define EXCESSD 1022L
#define HIDDEND (1L << 20L)
#define EXPDBITS 11
#define EXPDMASK 0x7FFL
#define EXPD(fp) (((fp.l.upper) >> 20L) & 0x7FFL)
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
(fp.l.lower >> 22))
#define MANTDMASK 0xFFFFFL
#define EXCESSX 16382L
#define HIDDENX (1L << 31L)
#define EXPXBITS 15
#define EXPXMASK 0x7FFF
#define EXPX(fp) (((fp.l.upper) >> 16) & EXPXMASK)
#define SIGNX(fp) ((fp.l.upper) & SIGNBIT)
#define MANTXMASK 0x7FFFFFFFL
union double_long
{
double d;
struct {
long upper;
unsigned long lower;
} l;
};
union float_long {
float f;
long l;
};
union long_double_long
{
long double ld;
struct
{
long upper;
unsigned long middle;
unsigned long lower;
} l;
};
#ifndef EXTFLOAT
int
__unordsf2(float a, float b)
{
union float_long fl;
fl.f = a;
if (EXP(fl.l) == EXP(~0u) && (MANT(fl.l) & ~HIDDEN) != 0)
return 1;
fl.f = b;
if (EXP(fl.l) == EXP(~0u) && (MANT(fl.l) & ~HIDDEN) != 0)
return 1;
return 0;
}
int
__unorddf2(double a, double b)
{
union double_long dl;
dl.d = a;
if (EXPD(dl) == EXPDMASK
&& ((dl.l.upper & MANTDMASK) != 0 || dl.l.lower != 0))
return 1;
dl.d = b;
if (EXPD(dl) == EXPDMASK
&& ((dl.l.upper & MANTDMASK) != 0 || dl.l.lower != 0))
return 1;
return 0;
}
double
__floatunsidf (unsigned long a1)
{
long exp = 32 + EXCESSD;
union double_long dl;
if (!a1)
{
dl.l.upper = dl.l.lower = 0;
return dl.d;
}
while (a1 < 0x2000000L)
{
a1 <<= 4;
exp -= 4;
}
while (a1 < 0x80000000L)
{
a1 <<= 1;
exp--;
}
dl.l.upper = exp << 20L;
dl.l.upper |= (a1 >> 11L) & ~HIDDEND;
dl.l.lower = a1 << 21L;
return dl.d;
}
double
__floatsidf (long a1)
{
long sign = 0, exp = 31 + EXCESSD;
union double_long dl;
if (!a1)
{
dl.l.upper = dl.l.lower = 0;
return dl.d;
}
if (a1 < 0)
{
sign = SIGNBIT;
a1 = (long)-(unsigned long)a1;
if (a1 < 0)
{
dl.l.upper = SIGNBIT | ((32 + EXCESSD) << 20L);
dl.l.lower = 0;
return dl.d;
}
}
while (a1 < 0x1000000L)
{
a1 <<= 4;
exp -= 4;
}
while (a1 < 0x40000000L)
{
a1 <<= 1;
exp--;
}
dl.l.upper = sign;
dl.l.upper |= exp << 20L;
dl.l.upper |= (a1 >> 10L) & ~HIDDEND;
dl.l.lower = a1 << 22L;
return dl.d;
}
float
__floatunsisf (unsigned long l)
{
double foo = __floatunsidf (l);
return foo;
}
float
__floatsisf (long l)
{
double foo = __floatsidf (l);
return foo;
}
double
__extendsfdf2 (float a1)
{
register union float_long fl1;
register union double_long dl;
register long exp;
register long mant;
fl1.f = a1;
dl.l.upper = SIGN (fl1.l);
if ((fl1.l & ~SIGNBIT) == 0)
{
dl.l.lower = 0;
return dl.d;
}
exp = EXP(fl1.l);
mant = MANT (fl1.l) & ~HIDDEN;
if (exp == 0)
{
exp = 1;
while (!(mant & HIDDEN))
{
mant <<= 1;
exp--;
}
mant &= ~HIDDEN;
}
exp = exp - EXCESS + EXCESSD;
dl.l.upper |= exp << 20;
dl.l.upper |= mant >> 3;
dl.l.lower = mant << 29;
return dl.d;
}
float
__truncdfsf2 (double a1)
{
register long exp;
register long mant;
register union float_long fl;
register union double_long dl1;
dl1.d = a1;
if ((dl1.l.upper & ~SIGNBIT) == 0 && !dl1.l.lower)
{
fl.l = SIGND(dl1);
return fl.f;
}
exp = EXPD (dl1) - EXCESSD + EXCESS;
mant = MANTD (dl1) >> 6;
if (exp <= 0)
{
if (exp < -24)
mant = 0;
else
mant >>= 1 - exp;
exp = 0;
}
mant += 1;
mant >>= 1;
if (mant & 0xFF000000L)
{
mant >>= 1;
exp++;
}
mant &= ~HIDDEN;
fl.l = PACK (SIGND (dl1), exp, mant);
return (fl.f);
}
long
__fixdfsi (double a1)
{
register union double_long dl1;
register long exp;
register long l;
dl1.d = a1;
if (!dl1.l.upper && !dl1.l.lower)
return 0;
exp = EXPD (dl1) - EXCESSD - 31;
l = MANTD (dl1);
if (exp > 0)
{
return SIGND (dl1) ? 0x80000000L : 0x7fffffffL;
}
if (exp <= -32)
return 0;
if (exp < 0)
l >>= -exp;
return (SIGND (dl1) ? -l : l);
}
long
__fixsfsi (float a1)
{
double foo = a1;
return __fixdfsi (foo);
}
#else
double __floatunsidf (unsigned long);
double __floatsidf (long);
float __floatsisf (long);
double __extendsfdf2 (float);
float __truncdfsf2 (double);
long __fixdfsi (double);
long __fixsfsi (float);
int
__unordxf2(long double a, long double b)
{
union long_double_long ldl;
ldl.ld = a;
if (EXPX(ldl) == EXPXMASK
&& ((ldl.l.middle & MANTXMASK) != 0 || ldl.l.lower != 0))
return 1;
ldl.ld = b;
if (EXPX(ldl) == EXPXMASK
&& ((ldl.l.middle & MANTXMASK) != 0 || ldl.l.lower != 0))
return 1;
return 0;
}
long double
__extenddfxf2 (double d)
{
register union double_long dl;
register union long_double_long ldl;
register long exp;
dl.d = d;
ldl.l.upper = SIGND (dl);
if ((dl.l.upper & ~SIGNBIT) == 0 && !dl.l.lower)
{
ldl.l.middle = 0;
ldl.l.lower = 0;
return ldl.ld;
}
exp = EXPD (dl) - EXCESSD + EXCESSX;
ldl.l.upper |= exp << 16;
ldl.l.middle = HIDDENX;
ldl.l.middle |= (dl.l.upper & MANTDMASK) << (31 - 20);
ldl.l.middle |= dl.l.lower >> (1 + 20);
ldl.l.lower = dl.l.lower << (32 - 21);
return ldl.ld;
}
double
__truncxfdf2 (long double ld)
{
register long exp;
register union double_long dl;
register union long_double_long ldl;
ldl.ld = ld;
dl.l.upper = SIGNX (ldl);
if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower)
{
dl.l.lower = 0;
return dl.d;
}
exp = EXPX (ldl) - EXCESSX + EXCESSD;
if (exp >= EXPDMASK)
exp = EXPDMASK - 1;
dl.l.upper |= exp << (32 - (EXPDBITS + 1));
dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1);
dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1));
dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1);
return dl.d;
}
long double
__extendsfxf2 (float f)
{
long double foo = __extenddfxf2 (__extendsfdf2 (f));
return foo;
}
float
__truncxfsf2 (long double ld)
{
float foo = __truncdfsf2 (__truncxfdf2 (ld));
return foo;
}
long double
__floatsixf (long l)
{
double foo = __floatsidf (l);
return foo;
}
long double
__floatunsixf (unsigned long l)
{
double foo = __floatunsidf (l);
return foo;
}
long
__fixxfsi (long double ld)
{
long foo = __fixdfsi ((double) ld);
return foo;
}
long double
__addxf3 (long double x1, long double x2)
{
return (double) x1 + (double) x2;
}
long double
__subxf3 (long double x1, long double x2)
{
return (double) x1 - (double) x2;
}
long double
__mulxf3 (long double x1, long double x2)
{
return (double) x1 * (double) x2;
}
long double
__divxf3 (long double x1, long double x2)
{
return (double) x1 / (double) x2;
}
long double
__negxf2 (long double x1)
{
return - (double) x1;
}
long
__cmpxf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
long
__eqxf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
long
__nexf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
long
__ltxf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
long
__lexf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
long
__gtxf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
long
__gexf2 (long double x1, long double x2)
{
return __cmpdf2 ((double) x1, (double) x2);
}
#endif