Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 6fb6d245

History | View | Annotate | Download (20.2 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
| Raises the exceptions specified by `flags'.  Floating-point traps can be
41 158142c2 bellard
| defined here if desired.  It is currently not possible for such a trap
42 158142c2 bellard
| to substitute a result value.  If traps are not implemented, this routine
43 158142c2 bellard
| should be simply `float_exception_flags |= flags;'.
44 158142c2 bellard
*----------------------------------------------------------------------------*/
45 158142c2 bellard
46 158142c2 bellard
void float_raise( int8 flags STATUS_PARAM )
47 158142c2 bellard
{
48 158142c2 bellard
    STATUS(float_exception_flags) |= flags;
49 158142c2 bellard
}
50 158142c2 bellard
51 158142c2 bellard
/*----------------------------------------------------------------------------
52 158142c2 bellard
| Internal canonical NaN format.
53 158142c2 bellard
*----------------------------------------------------------------------------*/
54 158142c2 bellard
typedef struct {
55 158142c2 bellard
    flag sign;
56 158142c2 bellard
    bits64 high, low;
57 158142c2 bellard
} commonNaNT;
58 158142c2 bellard
59 158142c2 bellard
/*----------------------------------------------------------------------------
60 158142c2 bellard
| The pattern for a default generated single-precision NaN.
61 158142c2 bellard
*----------------------------------------------------------------------------*/
62 85016c98 ths
#if defined(TARGET_SPARC)
63 85016c98 ths
#define float32_default_nan make_float32(0x7FFFFFFF)
64 9027db89 pbrook
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
65 85016c98 ths
#define float32_default_nan make_float32(0x7FC00000)
66 85016c98 ths
#elif defined(TARGET_HPPA)
67 85016c98 ths
#define float32_default_nan make_float32(0x7FA00000)
68 85016c98 ths
#elif SNAN_BIT_IS_ONE
69 f090c9d4 pbrook
#define float32_default_nan make_float32(0x7FBFFFFF)
70 b645bb48 ths
#else
71 f090c9d4 pbrook
#define float32_default_nan make_float32(0xFFC00000)
72 b645bb48 ths
#endif
73 158142c2 bellard
74 158142c2 bellard
/*----------------------------------------------------------------------------
75 5a6932d5 ths
| Returns 1 if the single-precision floating-point value `a' is a quiet
76 5a6932d5 ths
| NaN; otherwise returns 0.
77 158142c2 bellard
*----------------------------------------------------------------------------*/
78 158142c2 bellard
79 f090c9d4 pbrook
int float32_is_nan( float32 a_ )
80 158142c2 bellard
{
81 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
82 5a6932d5 ths
#if SNAN_BIT_IS_ONE
83 b645bb48 ths
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
84 b645bb48 ths
#else
85 b645bb48 ths
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
86 b645bb48 ths
#endif
87 158142c2 bellard
}
88 158142c2 bellard
89 158142c2 bellard
/*----------------------------------------------------------------------------
90 158142c2 bellard
| Returns 1 if the single-precision floating-point value `a' is a signaling
91 158142c2 bellard
| NaN; otherwise returns 0.
92 158142c2 bellard
*----------------------------------------------------------------------------*/
93 158142c2 bellard
94 f090c9d4 pbrook
int float32_is_signaling_nan( float32 a_ )
95 158142c2 bellard
{
96 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
97 5a6932d5 ths
#if SNAN_BIT_IS_ONE
98 b645bb48 ths
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
99 b645bb48 ths
#else
100 158142c2 bellard
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
101 b645bb48 ths
#endif
102 158142c2 bellard
}
103 158142c2 bellard
104 158142c2 bellard
/*----------------------------------------------------------------------------
105 158142c2 bellard
| Returns the result of converting the single-precision floating-point NaN
106 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
107 158142c2 bellard
| exception is raised.
108 158142c2 bellard
*----------------------------------------------------------------------------*/
109 158142c2 bellard
110 158142c2 bellard
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
111 158142c2 bellard
{
112 158142c2 bellard
    commonNaNT z;
113 158142c2 bellard
114 158142c2 bellard
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
115 f090c9d4 pbrook
    z.sign = float32_val(a)>>31;
116 158142c2 bellard
    z.low = 0;
117 f090c9d4 pbrook
    z.high = ( (bits64) float32_val(a) )<<41;
118 158142c2 bellard
    return z;
119 158142c2 bellard
}
120 158142c2 bellard
121 158142c2 bellard
/*----------------------------------------------------------------------------
122 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the single-
123 158142c2 bellard
| precision floating-point format.
124 158142c2 bellard
*----------------------------------------------------------------------------*/
125 158142c2 bellard
126 158142c2 bellard
static float32 commonNaNToFloat32( commonNaNT a )
127 158142c2 bellard
{
128 85016c98 ths
    bits32 mantissa = a.high>>41;
129 85016c98 ths
    if ( mantissa )
130 85016c98 ths
        return make_float32(
131 85016c98 ths
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
132 85016c98 ths
    else
133 85016c98 ths
        return float32_default_nan;
134 158142c2 bellard
}
135 158142c2 bellard
136 158142c2 bellard
/*----------------------------------------------------------------------------
137 158142c2 bellard
| Takes two single-precision floating-point values `a' and `b', one of which
138 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
139 158142c2 bellard
| signaling NaN, the invalid exception is raised.
140 158142c2 bellard
*----------------------------------------------------------------------------*/
141 158142c2 bellard
142 158142c2 bellard
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
143 158142c2 bellard
{
144 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
145 f090c9d4 pbrook
    bits32 av, bv, res;
146 158142c2 bellard
147 5c7908ed pbrook
    if ( STATUS(default_nan_mode) )
148 5c7908ed pbrook
        return float32_default_nan;
149 5c7908ed pbrook
150 158142c2 bellard
    aIsNaN = float32_is_nan( a );
151 158142c2 bellard
    aIsSignalingNaN = float32_is_signaling_nan( a );
152 158142c2 bellard
    bIsNaN = float32_is_nan( b );
153 158142c2 bellard
    bIsSignalingNaN = float32_is_signaling_nan( b );
154 f090c9d4 pbrook
    av = float32_val(a);
155 f090c9d4 pbrook
    bv = float32_val(b);
156 5a6932d5 ths
#if SNAN_BIT_IS_ONE
157 f090c9d4 pbrook
    av &= ~0x00400000;
158 f090c9d4 pbrook
    bv &= ~0x00400000;
159 b645bb48 ths
#else
160 f090c9d4 pbrook
    av |= 0x00400000;
161 f090c9d4 pbrook
    bv |= 0x00400000;
162 b645bb48 ths
#endif
163 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
164 158142c2 bellard
    if ( aIsSignalingNaN ) {
165 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
166 f090c9d4 pbrook
        res = bIsNaN ? bv : av;
167 158142c2 bellard
    }
168 158142c2 bellard
    else if ( aIsNaN ) {
169 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN )
170 f090c9d4 pbrook
            res = av;
171 f090c9d4 pbrook
        else {
172 158142c2 bellard
 returnLargerSignificand:
173 f090c9d4 pbrook
            if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
174 f090c9d4 pbrook
                res = bv;
175 f090c9d4 pbrook
            else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
176 f090c9d4 pbrook
                res = av;
177 f090c9d4 pbrook
            else
178 f090c9d4 pbrook
                res = ( av < bv ) ? av : bv;
179 f090c9d4 pbrook
        }
180 158142c2 bellard
    }
181 158142c2 bellard
    else {
182 f090c9d4 pbrook
        res = bv;
183 158142c2 bellard
    }
184 f090c9d4 pbrook
    return make_float32(res);
185 158142c2 bellard
}
186 158142c2 bellard
187 158142c2 bellard
/*----------------------------------------------------------------------------
188 158142c2 bellard
| The pattern for a default generated double-precision NaN.
189 158142c2 bellard
*----------------------------------------------------------------------------*/
190 85016c98 ths
#if defined(TARGET_SPARC)
191 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
192 9027db89 pbrook
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
193 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
194 85016c98 ths
#elif defined(TARGET_HPPA)
195 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
196 85016c98 ths
#elif SNAN_BIT_IS_ONE
197 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
198 b645bb48 ths
#else
199 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
200 b645bb48 ths
#endif
201 158142c2 bellard
202 158142c2 bellard
/*----------------------------------------------------------------------------
203 5a6932d5 ths
| Returns 1 if the double-precision floating-point value `a' is a quiet
204 5a6932d5 ths
| NaN; otherwise returns 0.
205 158142c2 bellard
*----------------------------------------------------------------------------*/
206 158142c2 bellard
207 f090c9d4 pbrook
int float64_is_nan( float64 a_ )
208 158142c2 bellard
{
209 f090c9d4 pbrook
    bits64 a = float64_val(a_);
210 5a6932d5 ths
#if SNAN_BIT_IS_ONE
211 b645bb48 ths
    return
212 b645bb48 ths
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
213 b645bb48 ths
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
214 b645bb48 ths
#else
215 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
216 b645bb48 ths
#endif
217 158142c2 bellard
}
218 158142c2 bellard
219 158142c2 bellard
/*----------------------------------------------------------------------------
220 158142c2 bellard
| Returns 1 if the double-precision floating-point value `a' is a signaling
221 158142c2 bellard
| NaN; otherwise returns 0.
222 158142c2 bellard
*----------------------------------------------------------------------------*/
223 158142c2 bellard
224 f090c9d4 pbrook
int float64_is_signaling_nan( float64 a_ )
225 158142c2 bellard
{
226 f090c9d4 pbrook
    bits64 a = float64_val(a_);
227 5a6932d5 ths
#if SNAN_BIT_IS_ONE
228 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
229 b645bb48 ths
#else
230 158142c2 bellard
    return
231 158142c2 bellard
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232 158142c2 bellard
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233 b645bb48 ths
#endif
234 158142c2 bellard
}
235 158142c2 bellard
236 158142c2 bellard
/*----------------------------------------------------------------------------
237 158142c2 bellard
| Returns the result of converting the double-precision floating-point NaN
238 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
239 158142c2 bellard
| exception is raised.
240 158142c2 bellard
*----------------------------------------------------------------------------*/
241 158142c2 bellard
242 158142c2 bellard
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
243 158142c2 bellard
{
244 158142c2 bellard
    commonNaNT z;
245 158142c2 bellard
246 158142c2 bellard
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
247 f090c9d4 pbrook
    z.sign = float64_val(a)>>63;
248 158142c2 bellard
    z.low = 0;
249 f090c9d4 pbrook
    z.high = float64_val(a)<<12;
250 158142c2 bellard
    return z;
251 158142c2 bellard
}
252 158142c2 bellard
253 158142c2 bellard
/*----------------------------------------------------------------------------
254 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the double-
255 158142c2 bellard
| precision floating-point format.
256 158142c2 bellard
*----------------------------------------------------------------------------*/
257 158142c2 bellard
258 158142c2 bellard
static float64 commonNaNToFloat64( commonNaNT a )
259 158142c2 bellard
{
260 85016c98 ths
    bits64 mantissa = a.high>>12;
261 85016c98 ths
262 85016c98 ths
    if ( mantissa )
263 85016c98 ths
        return make_float64(
264 85016c98 ths
              ( ( (bits64) a.sign )<<63 )
265 85016c98 ths
            | LIT64( 0x7FF0000000000000 )
266 85016c98 ths
            | ( a.high>>12 ));
267 85016c98 ths
    else
268 85016c98 ths
        return float64_default_nan;
269 158142c2 bellard
}
270 158142c2 bellard
271 158142c2 bellard
/*----------------------------------------------------------------------------
272 158142c2 bellard
| Takes two double-precision floating-point values `a' and `b', one of which
273 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
274 158142c2 bellard
| signaling NaN, the invalid exception is raised.
275 158142c2 bellard
*----------------------------------------------------------------------------*/
276 158142c2 bellard
277 158142c2 bellard
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
278 158142c2 bellard
{
279 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
280 f090c9d4 pbrook
    bits64 av, bv, res;
281 158142c2 bellard
282 5c7908ed pbrook
    if ( STATUS(default_nan_mode) )
283 5c7908ed pbrook
        return float64_default_nan;
284 5c7908ed pbrook
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 70c14705 blueswir1
        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 5c7908ed pbrook
    if ( STATUS(default_nan_mode) ) {
422 5c7908ed pbrook
        a.low = floatx80_default_nan_low;
423 5c7908ed pbrook
        a.high = floatx80_default_nan_high;
424 5c7908ed pbrook
        return a;
425 5c7908ed pbrook
    }
426 5c7908ed pbrook
427 158142c2 bellard
    aIsNaN = floatx80_is_nan( a );
428 158142c2 bellard
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
429 158142c2 bellard
    bIsNaN = floatx80_is_nan( b );
430 158142c2 bellard
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
431 5a6932d5 ths
#if SNAN_BIT_IS_ONE
432 5a6932d5 ths
    a.low &= ~LIT64( 0xC000000000000000 );
433 5a6932d5 ths
    b.low &= ~LIT64( 0xC000000000000000 );
434 5a6932d5 ths
#else
435 158142c2 bellard
    a.low |= LIT64( 0xC000000000000000 );
436 158142c2 bellard
    b.low |= LIT64( 0xC000000000000000 );
437 5a6932d5 ths
#endif
438 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
439 158142c2 bellard
    if ( aIsSignalingNaN ) {
440 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
441 158142c2 bellard
        return bIsNaN ? b : a;
442 158142c2 bellard
    }
443 158142c2 bellard
    else if ( aIsNaN ) {
444 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
445 158142c2 bellard
 returnLargerSignificand:
446 158142c2 bellard
        if ( a.low < b.low ) return b;
447 158142c2 bellard
        if ( b.low < a.low ) return a;
448 158142c2 bellard
        return ( a.high < b.high ) ? a : b;
449 158142c2 bellard
    }
450 158142c2 bellard
    else {
451 158142c2 bellard
        return b;
452 158142c2 bellard
    }
453 158142c2 bellard
}
454 158142c2 bellard
455 158142c2 bellard
#endif
456 158142c2 bellard
457 158142c2 bellard
#ifdef FLOAT128
458 158142c2 bellard
459 158142c2 bellard
/*----------------------------------------------------------------------------
460 158142c2 bellard
| The pattern for a default generated quadruple-precision NaN.  The `high' and
461 158142c2 bellard
| `low' values hold the most- and least-significant bits, respectively.
462 158142c2 bellard
*----------------------------------------------------------------------------*/
463 5a6932d5 ths
#if SNAN_BIT_IS_ONE
464 5a6932d5 ths
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
465 5a6932d5 ths
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
466 5a6932d5 ths
#else
467 158142c2 bellard
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
468 158142c2 bellard
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
469 5a6932d5 ths
#endif
470 158142c2 bellard
471 158142c2 bellard
/*----------------------------------------------------------------------------
472 5a6932d5 ths
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
473 5a6932d5 ths
| NaN; otherwise returns 0.
474 158142c2 bellard
*----------------------------------------------------------------------------*/
475 158142c2 bellard
476 750afe93 bellard
int float128_is_nan( float128 a )
477 158142c2 bellard
{
478 5a6932d5 ths
#if SNAN_BIT_IS_ONE
479 5a6932d5 ths
    return
480 5a6932d5 ths
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
481 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
482 5a6932d5 ths
#else
483 158142c2 bellard
    return
484 158142c2 bellard
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
485 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
486 5a6932d5 ths
#endif
487 158142c2 bellard
}
488 158142c2 bellard
489 158142c2 bellard
/*----------------------------------------------------------------------------
490 158142c2 bellard
| Returns 1 if the quadruple-precision floating-point value `a' is a
491 158142c2 bellard
| signaling NaN; otherwise returns 0.
492 158142c2 bellard
*----------------------------------------------------------------------------*/
493 158142c2 bellard
494 750afe93 bellard
int float128_is_signaling_nan( float128 a )
495 158142c2 bellard
{
496 5a6932d5 ths
#if SNAN_BIT_IS_ONE
497 5a6932d5 ths
    return
498 5a6932d5 ths
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
499 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
500 5a6932d5 ths
#else
501 158142c2 bellard
    return
502 158142c2 bellard
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
503 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
504 5a6932d5 ths
#endif
505 158142c2 bellard
}
506 158142c2 bellard
507 158142c2 bellard
/*----------------------------------------------------------------------------
508 158142c2 bellard
| Returns the result of converting the quadruple-precision floating-point NaN
509 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
510 158142c2 bellard
| exception is raised.
511 158142c2 bellard
*----------------------------------------------------------------------------*/
512 158142c2 bellard
513 158142c2 bellard
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
514 158142c2 bellard
{
515 158142c2 bellard
    commonNaNT z;
516 158142c2 bellard
517 158142c2 bellard
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
518 158142c2 bellard
    z.sign = a.high>>63;
519 158142c2 bellard
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
520 158142c2 bellard
    return z;
521 158142c2 bellard
}
522 158142c2 bellard
523 158142c2 bellard
/*----------------------------------------------------------------------------
524 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the quadruple-
525 158142c2 bellard
| precision floating-point format.
526 158142c2 bellard
*----------------------------------------------------------------------------*/
527 158142c2 bellard
528 158142c2 bellard
static float128 commonNaNToFloat128( commonNaNT a )
529 158142c2 bellard
{
530 158142c2 bellard
    float128 z;
531 158142c2 bellard
532 158142c2 bellard
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
533 85016c98 ths
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
534 158142c2 bellard
    return z;
535 158142c2 bellard
}
536 158142c2 bellard
537 158142c2 bellard
/*----------------------------------------------------------------------------
538 158142c2 bellard
| Takes two quadruple-precision floating-point values `a' and `b', one of
539 158142c2 bellard
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
540 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
541 158142c2 bellard
*----------------------------------------------------------------------------*/
542 158142c2 bellard
543 158142c2 bellard
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
544 158142c2 bellard
{
545 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
546 158142c2 bellard
547 5c7908ed pbrook
    if ( STATUS(default_nan_mode) ) {
548 5c7908ed pbrook
        a.low = float128_default_nan_low;
549 5c7908ed pbrook
        a.high = float128_default_nan_high;
550 5c7908ed pbrook
        return a;
551 5c7908ed pbrook
    }
552 5c7908ed pbrook
553 158142c2 bellard
    aIsNaN = float128_is_nan( a );
554 158142c2 bellard
    aIsSignalingNaN = float128_is_signaling_nan( a );
555 158142c2 bellard
    bIsNaN = float128_is_nan( b );
556 158142c2 bellard
    bIsSignalingNaN = float128_is_signaling_nan( b );
557 5a6932d5 ths
#if SNAN_BIT_IS_ONE
558 5a6932d5 ths
    a.high &= ~LIT64( 0x0000800000000000 );
559 5a6932d5 ths
    b.high &= ~LIT64( 0x0000800000000000 );
560 5a6932d5 ths
#else
561 158142c2 bellard
    a.high |= LIT64( 0x0000800000000000 );
562 158142c2 bellard
    b.high |= LIT64( 0x0000800000000000 );
563 5a6932d5 ths
#endif
564 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
565 158142c2 bellard
    if ( aIsSignalingNaN ) {
566 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
567 158142c2 bellard
        return bIsNaN ? b : a;
568 158142c2 bellard
    }
569 158142c2 bellard
    else if ( aIsNaN ) {
570 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
571 158142c2 bellard
 returnLargerSignificand:
572 158142c2 bellard
        if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
573 158142c2 bellard
        if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
574 158142c2 bellard
        return ( a.high < b.high ) ? a : b;
575 158142c2 bellard
    }
576 158142c2 bellard
    else {
577 158142c2 bellard
        return b;
578 158142c2 bellard
    }
579 158142c2 bellard
}
580 158142c2 bellard
581 158142c2 bellard
#endif