5 Stubs to check for extremities of (IEEE) floats,
6 the tests have been (artfully) lifted from the hbc-0.9999.3 (lib/fltcode.c)
9 All tests return non-zero values to indicate success.
11 (SOF 95/98 - Bugfixed and tidied up.)
14 - avoid hard-wiring the fact that on an
15 Alpha we repr. a StgFloat as a double.
16 (introduce int equivalent of {ASSIGN,PK}_FLT? )
21 #include "ieee-flpt.h"
22 #include "floatExtreme.h"
32 #ifdef IEEE_FLOATING_POINT
36 To recap, here's the representation of a double precision
37 IEEE floating point number:
39 sign 63 sign bit (0==positive, 1==negative)
40 exponent 62-52 exponent (biased by 1023)
41 fraction 51-0 fraction (bits to right of binary point)
48 union { double d; int i[2]; } u;
54 /* Spelt out for clarity */
57 return ( ( (hx & 0x7ff00000) == 0x7ff00000 ) && /* Is the exponent all ones? */
58 ( (hx & 0xfffff ) != 0 || /* and the mantissa non-zero? */
59 ((unsigned int)lx != 0) )
64 hx |= (unsigned int)(lx|(-lx))>>31;
66 r = (int)((unsigned int)(hx))>>31;
76 union { double d; int i[2]; } u;
83 /* Inf iff exponent is all ones, mantissa all zeros */
84 high &= 0x7fffffff; /* mask out sign bit */
85 high ^= 0x7ff00000; /* flip the exponent bits */
91 isDoubleDenormalized(d)
94 union { double d; int i[2]; } u;
99 /* A (single/double/quad) precision floating point number
102 - mantissa is non-zero.
103 - (don't care about setting of sign bit.)
109 iexp = high & (0x7ff << 20); /* Get at the exponent */
111 return ( (iexp == 0) && /* exponent all zero? */
112 ( (high & 0xfffff ) != 0 || /* and the mantissa non-zero? */
113 ((unsigned int)low != 0) )
119 isDoubleNegativeZero(d)
122 union { double d; int i[2]; } u;
126 /* sign (bit 63) set (only) => negative zero */
127 return (u.i[H] == 0x80000000 && u.i[L] == 0);
130 /* Same tests, this time for StgFloats. */
134 To recap, here's the representation of a single precision
135 IEEE floating point number:
137 sign 31 sign bit (0 == positive, 1 == negative)
138 exponent 30-23 exponent (biased by 127)
139 fraction 22-0 fraction (bits to right of binary point)
147 #if defined(alpha_TARGET_OS)
148 /* StgFloat = double on alphas */
149 return (isDoubleNaN(f));
152 union { StgFloat f; int i; } u;
155 /* Floating point NaN iff exponent is all ones, mantissa is
156 non-zero (but see below.) */
158 u.i &= 0x7fffffff; /* mask out sign bit */
159 u.i = 0x7f800000 - u.i; /* <0 if exponent is max and mantissa non-zero. */
160 r = (int)(((unsigned int)(u.i))>>31); /* Get at the sign.. */
163 /* In case we should ever want to distinguish.. */
164 #if 0 && WE_JUST_WANT_QUIET_NAN
166 iexp = u.i & (0xff << 23); /* Get at the exponent part.. */
168 return ( ( iexp == (int)0x7f800000 ) && /* exponent all ones. */
169 (u.i & (0x80 << 22) ) /* MSB of mantissa is set */
172 #if 0 && WE_WANT_SIGNALLING_NAN
173 /* Signalling/trapping NaN */
175 iexp = u.i & (0xff << 23); /* Get at the exponent part.. */
176 return ( ( iexp == (int)0x7f800000 ) && /* ..it's all ones. */
177 ((u.i & (0x80 << 22)) == 0) && /* MSB of mantissa is clear */
178 ((u.i & 0x7fffff) != 0) /* rest of mantissa is non-zero */
189 #if defined(alpha_TARGET_OS)
190 /* StgFloat = double on alphas */
191 return (isDoubleInfinite(f));
193 union { StgFloat f; int i; } u;
196 /* A float is Inf iff exponent is max (all ones),
197 and mantissa is min(all zeros.) */
199 u.i &= 0x7fffffff; /* mask out sign bit */
200 u.i ^= 0x7f800000; /* invert exponent bits */
206 isFloatDenormalized(f)
209 #if defined(alpha_TARGET_OS)
210 /* StgFloat = double on alphas */
211 return (isDoubleDenormalized(f));
214 union { StgFloat f; int i; } u;
217 iexp = u.i & (0xff << 23); /* Get at the exponent part */
218 imant = u.i & 0x3fffff; /* ditto, mantissa */
219 /* A (single/double/quad) precision floating point number
222 - mantissa is non-zero.
223 - (don't care about setting of sign bit.)
226 return ( (iexp == 0) && (imant != 0 ) );
231 isFloatNegativeZero(f)
234 #if defined(alpha_TARGET_OS)
235 /* StgFloat = double on alphas */
236 return (isDoubleNegativeZero(f));
238 union { StgFloat f; int i; } u;
241 /* sign (bit 31) set (only) => negative zero */
242 return (u.i == (int)0x80000000);
249 StgInt isDoubleNaN(d) StgDouble d; { return 0; }
250 StgInt isDoubleInfinite(d) StgDouble d; { return 0; }
251 StgInt isDoubleDenormalized(d) StgDouble d; { return 0; }
252 StgInt isDoubleNegativeZero(d) StgDouble d; { return 0; }
253 StgInt isFloatNaN(f) StgFloat f; { return 0; }
254 StgInt isFloatInfinite(f) StgFloat f; { return 0; }
255 StgInt isFloatDenormalized(f) StgFloat f; { return 0; }
256 StgInt isFloatNegativeZero(f) StgFloat f; { return 0; }