Skip to content
Snippets Groups Projects
Commit 52048c44 authored by sof's avatar sof
Browse files

[project @ 1998-05-08 10:23:08 by sof]

Cleaned up and fixed is*Denormalized buglet
parent 11a7b489
No related merge requests found
...@@ -6,6 +6,10 @@ Stubs to check for extremities of (IEEE) floats, ...@@ -6,6 +6,10 @@ Stubs to check for extremities of (IEEE) floats,
the tests have been (artfully) lifted from the hbc-0.9999.3 (lib/fltcode.c) the tests have been (artfully) lifted from the hbc-0.9999.3 (lib/fltcode.c)
source. source.
All tests return non-zero values to indicate success.
(SOF 95/98 - Bugfixed and tidied up.)
ToDo: ToDo:
- avoid hard-wiring the fact that on an - avoid hard-wiring the fact that on an
Alpha we repr. a StgFloat as a double. Alpha we repr. a StgFloat as a double.
...@@ -27,6 +31,16 @@ ToDo: ...@@ -27,6 +31,16 @@ ToDo:
#ifdef IEEE_FLOATING_POINT #ifdef IEEE_FLOATING_POINT
/*
To recap, here's the representation of a double precision
IEEE floating point number:
sign 63 sign bit (0==positive, 1==negative)
exponent 62-52 exponent (biased by 1023)
fraction 51-0 fraction (bits to right of binary point)
*/
StgInt StgInt
isDoubleNaN(d) isDoubleNaN(d)
StgDouble d; StgDouble d;
...@@ -36,13 +50,23 @@ StgDouble d; ...@@ -36,13 +50,23 @@ StgDouble d;
int r; int r;
u.d = d; u.d = d;
/* Spelt out for clarity */
hx = u.i[H]; hx = u.i[H];
lx = u.i[L]; lx = u.i[L];
return ( ( (hx & 0x7ff00000) == 0x7ff00000 ) && /* Is the exponent all ones? */
( (hx & 0xfffff ) != 0 || /* and the mantissa non-zero? */
((unsigned int)lx != 0) )
);
/* Old definition:
hx &= 0x7fffffff; hx &= 0x7fffffff;
hx |= (unsigned int)(lx|(-lx))>>31; hx |= (unsigned int)(lx|(-lx))>>31;
hx = 0x7ff00000 - hx; hx = 0x7ff00000 - hx;
r = (int)((unsigned int)(hx))>>31; r = (int)((unsigned int)(hx))>>31;
return (r); return (r);
*/
} }
StgInt StgInt
...@@ -50,15 +74,17 @@ isDoubleInfinite(d) ...@@ -50,15 +74,17 @@ isDoubleInfinite(d)
StgDouble d; StgDouble d;
{ {
union { double d; int i[2]; } u; union { double d; int i[2]; } u;
int hx,lx; int high,low;
u.d = d; u.d = d;
hx = u.i[H]; high = u.i[H];
lx = u.i[L]; low = u.i[L];
hx &= 0x7fffffff;
hx ^= 0x7ff00000; /* Inf iff exponent is all ones, mantissa all zeros */
hx |= lx; high &= 0x7fffffff; /* mask out sign bit */
return (hx == 0); high ^= 0x7ff00000; /* flip the exponent bits */
high |= low;
return (high == 0);
} }
StgInt StgInt
...@@ -66,12 +92,27 @@ isDoubleDenormalized(d) ...@@ -66,12 +92,27 @@ isDoubleDenormalized(d)
StgDouble d; StgDouble d;
{ {
union { double d; int i[2]; } u; union { double d; int i[2]; } u;
int high, iexp; int high, low, iexp;
u.d = d; u.d = d;
/* A (single/double/quad) precision floating point number
is denormalised iff:
- exponent is zero
- mantissa is non-zero.
- (don't care about setting of sign bit.)
*/
high = u.i[H]; high = u.i[H];
iexp = high & (0x7ff << 20); low = u.i[L];
return (iexp == 0); iexp = high & (0x7ff << 20); /* Get at the exponent */
return ( (iexp == 0) && /* exponent all zero? */
( (high & 0xfffff ) != 0 || /* and the mantissa non-zero? */
((unsigned int)low != 0) )
);
} }
StgInt StgInt
...@@ -82,27 +123,62 @@ StgDouble d; ...@@ -82,27 +123,62 @@ StgDouble d;
int high, iexp; int high, iexp;
u.d = d; u.d = d;
/* sign (bit 63) set (only) => negative zero */
return (u.i[H] == 0x80000000 && u.i[L] == 0); return (u.i[H] == 0x80000000 && u.i[L] == 0);
} }
/* Same tests, this time for StgFloats. */ /* Same tests, this time for StgFloats. */
/*
To recap, here's the representation of a single precision
IEEE floating point number:
sign 31 sign bit (0 == positive, 1 == negative)
exponent 30-23 exponent (biased by 127)
fraction 22-0 fraction (bits to right of binary point)
*/
StgInt StgInt
isFloatNaN(f) isFloatNaN(f)
StgFloat f; StgFloat f;
{ {
#if !defined(alpha_TARGET_OS) #if defined(alpha_TARGET_OS)
/* StgFloat = double on alphas */ /* StgFloat = double on alphas */
return (isDoubleNaN(f)); return (isDoubleNaN(f));
#else #else
union { StgFloat f; int i; } u;
int r; int r;
union { StgFloat f; int i; } u;
u.f = f; u.f = f;
u.i &= 0x7fffffff; /* Floating point NaN iff exponent is all ones, mantissa is
u.i = 0x7f800000 - u.i; non-zero (but see below.) */
r = (int)(((unsigned int)(u.i))>>31);
u.i &= 0x7fffffff; /* mask out sign bit */
u.i = 0x7f800000 - u.i; /* <0 if exponent is max and mantissa non-zero. */
r = (int)(((unsigned int)(u.i))>>31); /* Get at the sign.. */
return (r); return (r);
/* In case we should ever want to distinguish.. */
#if 0 && WE_JUST_WANT_QUIET_NAN
int iexp;
iexp = u.i & (0xff << 23); /* Get at the exponent part.. */
/* Quiet NaN */
return ( ( iexp == (int)0x7f800000 ) && /* exponent all ones. */
(u.i & (0x80 << 22) ) /* MSB of mantissa is set */
);
#endif
#if 0 && WE_WANT_SIGNALLING_NAN
/* Signalling/trapping NaN */
int iexp;
iexp = u.i & (0xff << 23); /* Get at the exponent part.. */
return ( ( iexp == (int)0x7f800000 ) && /* ..it's all ones. */
((u.i & (0x80 << 22)) == 0) && /* MSB of mantissa is clear */
((u.i & 0x7fffff) != 0) /* rest of mantissa is non-zero */
);
#endif
#endif #endif
} }
...@@ -110,16 +186,18 @@ StgInt ...@@ -110,16 +186,18 @@ StgInt
isFloatInfinite(f) isFloatInfinite(f)
StgFloat f; StgFloat f;
{ {
#if !defined(alpha_TARGET_OS) #if defined(alpha_TARGET_OS)
/* StgFloat = double on alphas */ /* StgFloat = double on alphas */
return (isDoubleInfinite(f)); return (isDoubleInfinite(f));
#else #else
int ix;
union { StgFloat f; int i; } u; union { StgFloat f; int i; } u;
u.f = f; u.f = f;
/* A float is Inf iff exponent is max (all ones),
and mantissa is min(all zeros.) */
u.i &= 0x7fffffff; u.i &= 0x7fffffff; /* mask out sign bit */
u.i ^= 0x7f800000; u.i ^= 0x7f800000; /* invert exponent bits */
return (u.i == 0); return (u.i == 0);
#endif #endif
} }
...@@ -128,16 +206,24 @@ StgInt ...@@ -128,16 +206,24 @@ StgInt
isFloatDenormalized(f) isFloatDenormalized(f)
StgFloat f; StgFloat f;
{ {
#if !defined(alpha_TARGET_OS) #if defined(alpha_TARGET_OS)
/* StgFloat = double on alphas */ /* StgFloat = double on alphas */
return (isDoubleDenormalized(f)); return (isDoubleDenormalized(f));
#else #else
int iexp; int iexp, imant;
union { StgFloat f; int i; } u; union { StgFloat f; int i; } u;
u.f = f; u.f = f;
iexp = u.i & (0xff << 23); iexp = u.i & (0xff << 23); /* Get at the exponent part */
return (iexp == 0); imant = u.i & 0x3fffff; /* ditto, mantissa */
/* A (single/double/quad) precision floating point number
is denormalised iff:
- exponent is zero
- mantissa is non-zero.
- (don't care about setting of sign bit.)
*/
return ( (iexp == 0) && (imant != 0 ) );
#endif #endif
} }
...@@ -145,13 +231,14 @@ StgInt ...@@ -145,13 +231,14 @@ StgInt
isFloatNegativeZero(f) isFloatNegativeZero(f)
StgFloat f; StgFloat f;
{ {
#if !defined(alpha_TARGET_OS) #if defined(alpha_TARGET_OS)
/* StgFloat = double on alphas */ /* StgFloat = double on alphas */
return (isDoubleNegativeZero(f)); return (isDoubleNegativeZero(f));
#else #else
union { StgFloat f; int i; } u; union { StgFloat f; int i; } u;
u.f = f; u.f = f;
/* sign (bit 31) set (only) => negative zero */
return (u.i == (int)0x80000000); return (u.i == (int)0x80000000);
#endif #endif
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment