Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 298e01b6

History | View | Annotate | Download (20 kB)

1 158142c2 bellard
2 158142c2 bellard
/*============================================================================
3 158142c2 bellard

4 158142c2 bellard
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 158142c2 bellard
Arithmetic Package, Release 2b.
6 158142c2 bellard

7 158142c2 bellard
Written by John R. Hauser.  This work was made possible in part by the
8 158142c2 bellard
International Computer Science Institute, located at Suite 600, 1947 Center
9 158142c2 bellard
Street, Berkeley, California 94704.  Funding was partially provided by the
10 158142c2 bellard
National Science Foundation under grant MIP-9311980.  The original version
11 158142c2 bellard
of this code was written as part of a project to build a fixed-point vector
12 158142c2 bellard
processor in collaboration with the University of California at Berkeley,
13 158142c2 bellard
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14 158142c2 bellard
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15 158142c2 bellard
arithmetic/SoftFloat.html'.
16 158142c2 bellard

17 158142c2 bellard
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18 158142c2 bellard
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19 158142c2 bellard
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20 158142c2 bellard
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21 158142c2 bellard
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22 158142c2 bellard
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23 158142c2 bellard
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24 158142c2 bellard
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25 158142c2 bellard

26 158142c2 bellard
Derivative works are acceptable, even for commercial purposes, so long as
27 158142c2 bellard
(1) the source code for the derivative work includes prominent notice that
28 158142c2 bellard
the work is derivative, and (2) the source code includes prominent notice with
29 158142c2 bellard
these four paragraphs for those parts of this code that are retained.
30 158142c2 bellard

31 158142c2 bellard
=============================================================================*/
32 158142c2 bellard
33 5a6932d5 ths
#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
34 5a6932d5 ths
#define SNAN_BIT_IS_ONE                1
35 5a6932d5 ths
#else
36 5a6932d5 ths
#define SNAN_BIT_IS_ONE                0
37 5a6932d5 ths
#endif
38 5a6932d5 ths
39 158142c2 bellard
/*----------------------------------------------------------------------------
40 158142c2 bellard
| Underflow tininess-detection mode, statically initialized to default value.
41 158142c2 bellard
| (The declaration in `softfloat.h' must match the `int8' type here.)
42 158142c2 bellard
*----------------------------------------------------------------------------*/
43 158142c2 bellard
int8 float_detect_tininess = float_tininess_after_rounding;
44 158142c2 bellard
45 158142c2 bellard
/*----------------------------------------------------------------------------
46 158142c2 bellard
| Raises the exceptions specified by `flags'.  Floating-point traps can be
47 158142c2 bellard
| defined here if desired.  It is currently not possible for such a trap
48 158142c2 bellard
| to substitute a result value.  If traps are not implemented, this routine
49 158142c2 bellard
| should be simply `float_exception_flags |= flags;'.
50 158142c2 bellard
*----------------------------------------------------------------------------*/
51 158142c2 bellard
52 158142c2 bellard
void float_raise( int8 flags STATUS_PARAM )
53 158142c2 bellard
{
54 158142c2 bellard
    STATUS(float_exception_flags) |= flags;
55 158142c2 bellard
}
56 158142c2 bellard
57 158142c2 bellard
/*----------------------------------------------------------------------------
58 158142c2 bellard
| Internal canonical NaN format.
59 158142c2 bellard
*----------------------------------------------------------------------------*/
60 158142c2 bellard
typedef struct {
61 158142c2 bellard
    flag sign;
62 158142c2 bellard
    bits64 high, low;
63 158142c2 bellard
} commonNaNT;
64 158142c2 bellard
65 158142c2 bellard
/*----------------------------------------------------------------------------
66 158142c2 bellard
| The pattern for a default generated single-precision NaN.
67 158142c2 bellard
*----------------------------------------------------------------------------*/
68 85016c98 ths
#if defined(TARGET_SPARC)
69 85016c98 ths
#define float32_default_nan make_float32(0x7FFFFFFF)
70 85016c98 ths
#elif defined(TARGET_POWERPC)
71 85016c98 ths
#define float32_default_nan make_float32(0x7FC00000)
72 85016c98 ths
#elif defined(TARGET_HPPA)
73 85016c98 ths
#define float32_default_nan make_float32(0x7FA00000)
74 85016c98 ths
#elif SNAN_BIT_IS_ONE
75 f090c9d4 pbrook
#define float32_default_nan make_float32(0x7FBFFFFF)
76 b645bb48 ths
#else
77 f090c9d4 pbrook
#define float32_default_nan make_float32(0xFFC00000)
78 b645bb48 ths
#endif
79 158142c2 bellard
80 158142c2 bellard
/*----------------------------------------------------------------------------
81 5a6932d5 ths
| Returns 1 if the single-precision floating-point value `a' is a quiet
82 5a6932d5 ths
| NaN; otherwise returns 0.
83 158142c2 bellard
*----------------------------------------------------------------------------*/
84 158142c2 bellard
85 f090c9d4 pbrook
int float32_is_nan( float32 a_ )
86 158142c2 bellard
{
87 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
88 5a6932d5 ths
#if SNAN_BIT_IS_ONE
89 b645bb48 ths
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
90 b645bb48 ths
#else
91 b645bb48 ths
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
92 b645bb48 ths
#endif
93 158142c2 bellard
}
94 158142c2 bellard
95 158142c2 bellard
/*----------------------------------------------------------------------------
96 158142c2 bellard
| Returns 1 if the single-precision floating-point value `a' is a signaling
97 158142c2 bellard
| NaN; otherwise returns 0.
98 158142c2 bellard
*----------------------------------------------------------------------------*/
99 158142c2 bellard
100 f090c9d4 pbrook
int float32_is_signaling_nan( float32 a_ )
101 158142c2 bellard
{
102 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
103 5a6932d5 ths
#if SNAN_BIT_IS_ONE
104 b645bb48 ths
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
105 b645bb48 ths
#else
106 158142c2 bellard
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
107 b645bb48 ths
#endif
108 158142c2 bellard
}
109 158142c2 bellard
110 158142c2 bellard
/*----------------------------------------------------------------------------
111 158142c2 bellard
| Returns the result of converting the single-precision floating-point NaN
112 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
113 158142c2 bellard
| exception is raised.
114 158142c2 bellard
*----------------------------------------------------------------------------*/
115 158142c2 bellard
116 158142c2 bellard
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
117 158142c2 bellard
{
118 158142c2 bellard
    commonNaNT z;
119 158142c2 bellard
120 158142c2 bellard
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
121 f090c9d4 pbrook
    z.sign = float32_val(a)>>31;
122 158142c2 bellard
    z.low = 0;
123 f090c9d4 pbrook
    z.high = ( (bits64) float32_val(a) )<<41;
124 158142c2 bellard
    return z;
125 158142c2 bellard
}
126 158142c2 bellard
127 158142c2 bellard
/*----------------------------------------------------------------------------
128 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the single-
129 158142c2 bellard
| precision floating-point format.
130 158142c2 bellard
*----------------------------------------------------------------------------*/
131 158142c2 bellard
132 158142c2 bellard
static float32 commonNaNToFloat32( commonNaNT a )
133 158142c2 bellard
{
134 85016c98 ths
    bits32 mantissa = a.high>>41;
135 85016c98 ths
    if ( mantissa )
136 85016c98 ths
        return make_float32(
137 85016c98 ths
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
138 85016c98 ths
    else
139 85016c98 ths
        return float32_default_nan;
140 158142c2 bellard
}
141 158142c2 bellard
142 158142c2 bellard
/*----------------------------------------------------------------------------
143 158142c2 bellard
| Takes two single-precision floating-point values `a' and `b', one of which
144 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
145 158142c2 bellard
| signaling NaN, the invalid exception is raised.
146 158142c2 bellard
*----------------------------------------------------------------------------*/
147 158142c2 bellard
148 158142c2 bellard
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
149 158142c2 bellard
{
150 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
151 f090c9d4 pbrook
    bits32 av, bv, res;
152 158142c2 bellard
153 158142c2 bellard
    aIsNaN = float32_is_nan( a );
154 158142c2 bellard
    aIsSignalingNaN = float32_is_signaling_nan( a );
155 158142c2 bellard
    bIsNaN = float32_is_nan( b );
156 158142c2 bellard
    bIsSignalingNaN = float32_is_signaling_nan( b );
157 f090c9d4 pbrook
    av = float32_val(a);
158 f090c9d4 pbrook
    bv = float32_val(b);
159 5a6932d5 ths
#if SNAN_BIT_IS_ONE
160 f090c9d4 pbrook
    av &= ~0x00400000;
161 f090c9d4 pbrook
    bv &= ~0x00400000;
162 b645bb48 ths
#else
163 f090c9d4 pbrook
    av |= 0x00400000;
164 f090c9d4 pbrook
    bv |= 0x00400000;
165 b645bb48 ths
#endif
166 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
167 158142c2 bellard
    if ( aIsSignalingNaN ) {
168 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
169 f090c9d4 pbrook
        res = bIsNaN ? bv : av;
170 158142c2 bellard
    }
171 158142c2 bellard
    else if ( aIsNaN ) {
172 f090c9d4 pbrook
        if ( bIsSignalingNaN | ! bIsNaN )
173 f090c9d4 pbrook
            res = av;
174 f090c9d4 pbrook
        else {
175 158142c2 bellard
 returnLargerSignificand:
176 f090c9d4 pbrook
            if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
177 f090c9d4 pbrook
                res = bv;
178 f090c9d4 pbrook
            else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
179 f090c9d4 pbrook
                res = av;
180 f090c9d4 pbrook
            else
181 f090c9d4 pbrook
                res = ( av < bv ) ? av : bv;
182 f090c9d4 pbrook
        }
183 158142c2 bellard
    }
184 158142c2 bellard
    else {
185 f090c9d4 pbrook
        res = bv;
186 158142c2 bellard
    }
187 f090c9d4 pbrook
    return make_float32(res);
188 158142c2 bellard
}
189 158142c2 bellard
190 158142c2 bellard
/*----------------------------------------------------------------------------
191 158142c2 bellard
| The pattern for a default generated double-precision NaN.
192 158142c2 bellard
*----------------------------------------------------------------------------*/
193 85016c98 ths
#if defined(TARGET_SPARC)
194 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
195 85016c98 ths
#elif defined(TARGET_POWERPC)
196 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
197 85016c98 ths
#elif defined(TARGET_HPPA)
198 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
199 85016c98 ths
#elif SNAN_BIT_IS_ONE
200 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
201 b645bb48 ths
#else
202 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
203 b645bb48 ths
#endif
204 158142c2 bellard
205 158142c2 bellard
/*----------------------------------------------------------------------------
206 5a6932d5 ths
| Returns 1 if the double-precision floating-point value `a' is a quiet
207 5a6932d5 ths
| NaN; otherwise returns 0.
208 158142c2 bellard
*----------------------------------------------------------------------------*/
209 158142c2 bellard
210 f090c9d4 pbrook
int float64_is_nan( float64 a_ )
211 158142c2 bellard
{
212 f090c9d4 pbrook
    bits64 a = float64_val(a_);
213 5a6932d5 ths
#if SNAN_BIT_IS_ONE
214 b645bb48 ths
    return
215 b645bb48 ths
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
216 b645bb48 ths
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
217 b645bb48 ths
#else
218 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
219 b645bb48 ths
#endif
220 158142c2 bellard
}
221 158142c2 bellard
222 158142c2 bellard
/*----------------------------------------------------------------------------
223 158142c2 bellard
| Returns 1 if the double-precision floating-point value `a' is a signaling
224 158142c2 bellard
| NaN; otherwise returns 0.
225 158142c2 bellard
*----------------------------------------------------------------------------*/
226 158142c2 bellard
227 f090c9d4 pbrook
int float64_is_signaling_nan( float64 a_ )
228 158142c2 bellard
{
229 f090c9d4 pbrook
    bits64 a = float64_val(a_);
230 5a6932d5 ths
#if SNAN_BIT_IS_ONE
231 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
232 b645bb48 ths
#else
233 158142c2 bellard
    return
234 158142c2 bellard
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
235 158142c2 bellard
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
236 b645bb48 ths
#endif
237 158142c2 bellard
}
238 158142c2 bellard
239 158142c2 bellard
/*----------------------------------------------------------------------------
240 158142c2 bellard
| Returns the result of converting the double-precision floating-point NaN
241 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
242 158142c2 bellard
| exception is raised.
243 158142c2 bellard
*----------------------------------------------------------------------------*/
244 158142c2 bellard
245 158142c2 bellard
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
246 158142c2 bellard
{
247 158142c2 bellard
    commonNaNT z;
248 158142c2 bellard
249 158142c2 bellard
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
250 f090c9d4 pbrook
    z.sign = float64_val(a)>>63;
251 158142c2 bellard
    z.low = 0;
252 f090c9d4 pbrook
    z.high = float64_val(a)<<12;
253 158142c2 bellard
    return z;
254 158142c2 bellard
}
255 158142c2 bellard
256 158142c2 bellard
/*----------------------------------------------------------------------------
257 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the double-
258 158142c2 bellard
| precision floating-point format.
259 158142c2 bellard
*----------------------------------------------------------------------------*/
260 158142c2 bellard
261 158142c2 bellard
static float64 commonNaNToFloat64( commonNaNT a )
262 158142c2 bellard
{
263 85016c98 ths
    bits64 mantissa = a.high>>12;
264 85016c98 ths
265 85016c98 ths
    if ( mantissa )
266 85016c98 ths
        return make_float64(
267 85016c98 ths
              ( ( (bits64) a.sign )<<63 )
268 85016c98 ths
            | LIT64( 0x7FF0000000000000 )
269 85016c98 ths
            | ( a.high>>12 ));
270 85016c98 ths
    else
271 85016c98 ths
        return float64_default_nan;
272 158142c2 bellard
}
273 158142c2 bellard
274 158142c2 bellard
/*----------------------------------------------------------------------------
275 158142c2 bellard
| Takes two double-precision floating-point values `a' and `b', one of which
276 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
277 158142c2 bellard
| signaling NaN, the invalid exception is raised.
278 158142c2 bellard
*----------------------------------------------------------------------------*/
279 158142c2 bellard
280 158142c2 bellard
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
281 158142c2 bellard
{
282 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
283 f090c9d4 pbrook
    bits64 av, bv, res;
284 158142c2 bellard
285 158142c2 bellard
    aIsNaN = float64_is_nan( a );
286 158142c2 bellard
    aIsSignalingNaN = float64_is_signaling_nan( a );
287 158142c2 bellard
    bIsNaN = float64_is_nan( b );
288 158142c2 bellard
    bIsSignalingNaN = float64_is_signaling_nan( b );
289 f090c9d4 pbrook
    av = float64_val(a);
290 f090c9d4 pbrook
    bv = float64_val(b);
291 5a6932d5 ths
#if SNAN_BIT_IS_ONE
292 f090c9d4 pbrook
    av &= ~LIT64( 0x0008000000000000 );
293 f090c9d4 pbrook
    bv &= ~LIT64( 0x0008000000000000 );
294 b645bb48 ths
#else
295 f090c9d4 pbrook
    av |= LIT64( 0x0008000000000000 );
296 f090c9d4 pbrook
    bv |= LIT64( 0x0008000000000000 );
297 b645bb48 ths
#endif
298 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
299 158142c2 bellard
    if ( aIsSignalingNaN ) {
300 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
301 f090c9d4 pbrook
        res = bIsNaN ? bv : av;
302 158142c2 bellard
    }
303 158142c2 bellard
    else if ( aIsNaN ) {
304 f090c9d4 pbrook
        if ( bIsSignalingNaN | ! bIsNaN )
305 f090c9d4 pbrook
            res = av;
306 f090c9d4 pbrook
        else {
307 158142c2 bellard
 returnLargerSignificand:
308 f090c9d4 pbrook
            if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
309 f090c9d4 pbrook
                res = bv;
310 f090c9d4 pbrook
            else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
311 f090c9d4 pbrook
                res = av;
312 f090c9d4 pbrook
            else
313 f090c9d4 pbrook
                res = ( av < bv ) ? av : bv;
314 f090c9d4 pbrook
        }
315 158142c2 bellard
    }
316 158142c2 bellard
    else {
317 f090c9d4 pbrook
        res = bv;
318 158142c2 bellard
    }
319 f090c9d4 pbrook
    return make_float64(res);
320 158142c2 bellard
}
321 158142c2 bellard
322 158142c2 bellard
#ifdef FLOATX80
323 158142c2 bellard
324 158142c2 bellard
/*----------------------------------------------------------------------------
325 158142c2 bellard
| The pattern for a default generated extended double-precision NaN.  The
326 158142c2 bellard
| `high' and `low' values hold the most- and least-significant bits,
327 158142c2 bellard
| respectively.
328 158142c2 bellard
*----------------------------------------------------------------------------*/
329 5a6932d5 ths
#if SNAN_BIT_IS_ONE
330 5a6932d5 ths
#define floatx80_default_nan_high 0x7FFF
331 5a6932d5 ths
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
332 5a6932d5 ths
#else
333 158142c2 bellard
#define floatx80_default_nan_high 0xFFFF
334 158142c2 bellard
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
335 5a6932d5 ths
#endif
336 158142c2 bellard
337 158142c2 bellard
/*----------------------------------------------------------------------------
338 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
339 5a6932d5 ths
| quiet NaN; otherwise returns 0.
340 158142c2 bellard
*----------------------------------------------------------------------------*/
341 158142c2 bellard
342 750afe93 bellard
int floatx80_is_nan( floatx80 a )
343 158142c2 bellard
{
344 5a6932d5 ths
#if SNAN_BIT_IS_ONE
345 5a6932d5 ths
    bits64 aLow;
346 158142c2 bellard
347 5a6932d5 ths
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
348 5a6932d5 ths
    return
349 5a6932d5 ths
           ( ( a.high & 0x7FFF ) == 0x7FFF )
350 5a6932d5 ths
        && (bits64) ( aLow<<1 )
351 5a6932d5 ths
        && ( a.low == aLow );
352 5a6932d5 ths
#else
353 158142c2 bellard
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
354 5a6932d5 ths
#endif
355 158142c2 bellard
}
356 158142c2 bellard
357 158142c2 bellard
/*----------------------------------------------------------------------------
358 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
359 158142c2 bellard
| signaling NaN; otherwise returns 0.
360 158142c2 bellard
*----------------------------------------------------------------------------*/
361 158142c2 bellard
362 750afe93 bellard
int floatx80_is_signaling_nan( floatx80 a )
363 158142c2 bellard
{
364 5a6932d5 ths
#if SNAN_BIT_IS_ONE
365 5a6932d5 ths
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
366 5a6932d5 ths
#else
367 158142c2 bellard
    bits64 aLow;
368 158142c2 bellard
369 158142c2 bellard
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
370 158142c2 bellard
    return
371 158142c2 bellard
           ( ( a.high & 0x7FFF ) == 0x7FFF )
372 158142c2 bellard
        && (bits64) ( aLow<<1 )
373 158142c2 bellard
        && ( a.low == aLow );
374 5a6932d5 ths
#endif
375 158142c2 bellard
}
376 158142c2 bellard
377 158142c2 bellard
/*----------------------------------------------------------------------------
378 158142c2 bellard
| Returns the result of converting the extended double-precision floating-
379 158142c2 bellard
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
380 158142c2 bellard
| invalid exception is raised.
381 158142c2 bellard
*----------------------------------------------------------------------------*/
382 158142c2 bellard
383 158142c2 bellard
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
384 158142c2 bellard
{
385 158142c2 bellard
    commonNaNT z;
386 158142c2 bellard
387 158142c2 bellard
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
388 158142c2 bellard
    z.sign = a.high>>15;
389 158142c2 bellard
    z.low = 0;
390 85016c98 ths
    z.high = a.low;
391 158142c2 bellard
    return z;
392 158142c2 bellard
}
393 158142c2 bellard
394 158142c2 bellard
/*----------------------------------------------------------------------------
395 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the extended
396 158142c2 bellard
| double-precision floating-point format.
397 158142c2 bellard
*----------------------------------------------------------------------------*/
398 158142c2 bellard
399 158142c2 bellard
static floatx80 commonNaNToFloatx80( commonNaNT a )
400 158142c2 bellard
{
401 158142c2 bellard
    floatx80 z;
402 158142c2 bellard
403 85016c98 ths
    if (a.high)
404 85016c98 ths
        z.low = a.high;
405 85016c98 ths
    else
406 85016c98 ths
        z.low = floatx80_default_nan_low;
407 158142c2 bellard
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
408 158142c2 bellard
    return z;
409 158142c2 bellard
}
410 158142c2 bellard
411 158142c2 bellard
/*----------------------------------------------------------------------------
412 158142c2 bellard
| Takes two extended double-precision floating-point values `a' and `b', one
413 158142c2 bellard
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
414 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
415 158142c2 bellard
*----------------------------------------------------------------------------*/
416 158142c2 bellard
417 158142c2 bellard
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
418 158142c2 bellard
{
419 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
420 158142c2 bellard
421 158142c2 bellard
    aIsNaN = floatx80_is_nan( a );
422 158142c2 bellard
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
423 158142c2 bellard
    bIsNaN = floatx80_is_nan( b );
424 158142c2 bellard
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
425 5a6932d5 ths
#if SNAN_BIT_IS_ONE
426 5a6932d5 ths
    a.low &= ~LIT64( 0xC000000000000000 );
427 5a6932d5 ths
    b.low &= ~LIT64( 0xC000000000000000 );
428 5a6932d5 ths
#else
429 158142c2 bellard
    a.low |= LIT64( 0xC000000000000000 );
430 158142c2 bellard
    b.low |= LIT64( 0xC000000000000000 );
431 5a6932d5 ths
#endif
432 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
433 158142c2 bellard
    if ( aIsSignalingNaN ) {
434 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
435 158142c2 bellard
        return bIsNaN ? b : a;
436 158142c2 bellard
    }
437 158142c2 bellard
    else if ( aIsNaN ) {
438 158142c2 bellard
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
439 158142c2 bellard
 returnLargerSignificand:
440 158142c2 bellard
        if ( a.low < b.low ) return b;
441 158142c2 bellard
        if ( b.low < a.low ) return a;
442 158142c2 bellard
        return ( a.high < b.high ) ? a : b;
443 158142c2 bellard
    }
444 158142c2 bellard
    else {
445 158142c2 bellard
        return b;
446 158142c2 bellard
    }
447 158142c2 bellard
}
448 158142c2 bellard
449 158142c2 bellard
#endif
450 158142c2 bellard
451 158142c2 bellard
#ifdef FLOAT128
452 158142c2 bellard
453 158142c2 bellard
/*----------------------------------------------------------------------------
454 158142c2 bellard
| The pattern for a default generated quadruple-precision NaN.  The `high' and
455 158142c2 bellard
| `low' values hold the most- and least-significant bits, respectively.
456 158142c2 bellard
*----------------------------------------------------------------------------*/
457 5a6932d5 ths
#if SNAN_BIT_IS_ONE
458 5a6932d5 ths
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
459 5a6932d5 ths
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
460 5a6932d5 ths
#else
461 158142c2 bellard
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
462 158142c2 bellard
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
463 5a6932d5 ths
#endif
464 158142c2 bellard
465 158142c2 bellard
/*----------------------------------------------------------------------------
466 5a6932d5 ths
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
467 5a6932d5 ths
| NaN; otherwise returns 0.
468 158142c2 bellard
*----------------------------------------------------------------------------*/
469 158142c2 bellard
470 750afe93 bellard
int float128_is_nan( float128 a )
471 158142c2 bellard
{
472 5a6932d5 ths
#if SNAN_BIT_IS_ONE
473 5a6932d5 ths
    return
474 5a6932d5 ths
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
475 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
476 5a6932d5 ths
#else
477 158142c2 bellard
    return
478 158142c2 bellard
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
479 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
480 5a6932d5 ths
#endif
481 158142c2 bellard
}
482 158142c2 bellard
483 158142c2 bellard
/*----------------------------------------------------------------------------
484 158142c2 bellard
| Returns 1 if the quadruple-precision floating-point value `a' is a
485 158142c2 bellard
| signaling NaN; otherwise returns 0.
486 158142c2 bellard
*----------------------------------------------------------------------------*/
487 158142c2 bellard
488 750afe93 bellard
int float128_is_signaling_nan( float128 a )
489 158142c2 bellard
{
490 5a6932d5 ths
#if SNAN_BIT_IS_ONE
491 5a6932d5 ths
    return
492 5a6932d5 ths
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
493 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
494 5a6932d5 ths
#else
495 158142c2 bellard
    return
496 158142c2 bellard
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
497 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
498 5a6932d5 ths
#endif
499 158142c2 bellard
}
500 158142c2 bellard
501 158142c2 bellard
/*----------------------------------------------------------------------------
502 158142c2 bellard
| Returns the result of converting the quadruple-precision floating-point NaN
503 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
504 158142c2 bellard
| exception is raised.
505 158142c2 bellard
*----------------------------------------------------------------------------*/
506 158142c2 bellard
507 158142c2 bellard
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
508 158142c2 bellard
{
509 158142c2 bellard
    commonNaNT z;
510 158142c2 bellard
511 158142c2 bellard
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
512 158142c2 bellard
    z.sign = a.high>>63;
513 158142c2 bellard
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
514 158142c2 bellard
    return z;
515 158142c2 bellard
}
516 158142c2 bellard
517 158142c2 bellard
/*----------------------------------------------------------------------------
518 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the quadruple-
519 158142c2 bellard
| precision floating-point format.
520 158142c2 bellard
*----------------------------------------------------------------------------*/
521 158142c2 bellard
522 158142c2 bellard
static float128 commonNaNToFloat128( commonNaNT a )
523 158142c2 bellard
{
524 158142c2 bellard
    float128 z;
525 158142c2 bellard
526 158142c2 bellard
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
527 85016c98 ths
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
528 158142c2 bellard
    return z;
529 158142c2 bellard
}
530 158142c2 bellard
531 158142c2 bellard
/*----------------------------------------------------------------------------
532 158142c2 bellard
| Takes two quadruple-precision floating-point values `a' and `b', one of
533 158142c2 bellard
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
534 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
535 158142c2 bellard
*----------------------------------------------------------------------------*/
536 158142c2 bellard
537 158142c2 bellard
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
538 158142c2 bellard
{
539 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
540 158142c2 bellard
541 158142c2 bellard
    aIsNaN = float128_is_nan( a );
542 158142c2 bellard
    aIsSignalingNaN = float128_is_signaling_nan( a );
543 158142c2 bellard
    bIsNaN = float128_is_nan( b );
544 158142c2 bellard
    bIsSignalingNaN = float128_is_signaling_nan( b );
545 5a6932d5 ths
#if SNAN_BIT_IS_ONE
546 5a6932d5 ths
    a.high &= ~LIT64( 0x0000800000000000 );
547 5a6932d5 ths
    b.high &= ~LIT64( 0x0000800000000000 );
548 5a6932d5 ths
#else
549 158142c2 bellard
    a.high |= LIT64( 0x0000800000000000 );
550 158142c2 bellard
    b.high |= LIT64( 0x0000800000000000 );
551 5a6932d5 ths
#endif
552 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
553 158142c2 bellard
    if ( aIsSignalingNaN ) {
554 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
555 158142c2 bellard
        return bIsNaN ? b : a;
556 158142c2 bellard
    }
557 158142c2 bellard
    else if ( aIsNaN ) {
558 158142c2 bellard
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
559 158142c2 bellard
 returnLargerSignificand:
560 158142c2 bellard
        if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
561 158142c2 bellard
        if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
562 158142c2 bellard
        return ( a.high < b.high ) ? a : b;
563 158142c2 bellard
    }
564 158142c2 bellard
    else {
565 158142c2 bellard
        return b;
566 158142c2 bellard
    }
567 158142c2 bellard
}
568 158142c2 bellard
569 158142c2 bellard
#endif