Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 18569871

History | View | Annotate | Download (21.4 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 990b3e19 Richard Henderson
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
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 18569871 Peter Maydell
int float32_is_quiet_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 b408dbde Peter Maydell
| Returns a quiet NaN if the single-precision floating point value `a' is a
106 b408dbde Peter Maydell
| signaling NaN; otherwise returns `a'.
107 b408dbde Peter Maydell
*----------------------------------------------------------------------------*/
108 b408dbde Peter Maydell
109 b408dbde Peter Maydell
float32 float32_maybe_silence_nan( float32 a_ )
110 b408dbde Peter Maydell
{
111 b408dbde Peter Maydell
    if (float32_is_signaling_nan(a_)) {
112 b408dbde Peter Maydell
        uint32_t a = float32_val(a_);
113 b408dbde Peter Maydell
#if SNAN_BIT_IS_ONE
114 b408dbde Peter Maydell
        a &= ~(1 << 22);
115 b408dbde Peter Maydell
#else
116 b408dbde Peter Maydell
        a |= (1 << 22);
117 b408dbde Peter Maydell
#endif
118 b408dbde Peter Maydell
        return make_float32(a);
119 b408dbde Peter Maydell
    }
120 b408dbde Peter Maydell
    return a_;
121 b408dbde Peter Maydell
}
122 b408dbde Peter Maydell
123 b408dbde Peter Maydell
/*----------------------------------------------------------------------------
124 158142c2 bellard
| Returns the result of converting the single-precision floating-point NaN
125 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
126 158142c2 bellard
| exception is raised.
127 158142c2 bellard
*----------------------------------------------------------------------------*/
128 158142c2 bellard
129 158142c2 bellard
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
130 158142c2 bellard
{
131 158142c2 bellard
    commonNaNT z;
132 158142c2 bellard
133 158142c2 bellard
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
134 f090c9d4 pbrook
    z.sign = float32_val(a)>>31;
135 158142c2 bellard
    z.low = 0;
136 f090c9d4 pbrook
    z.high = ( (bits64) float32_val(a) )<<41;
137 158142c2 bellard
    return z;
138 158142c2 bellard
}
139 158142c2 bellard
140 158142c2 bellard
/*----------------------------------------------------------------------------
141 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the single-
142 158142c2 bellard
| precision floating-point format.
143 158142c2 bellard
*----------------------------------------------------------------------------*/
144 158142c2 bellard
145 158142c2 bellard
static float32 commonNaNToFloat32( commonNaNT a )
146 158142c2 bellard
{
147 85016c98 ths
    bits32 mantissa = a.high>>41;
148 85016c98 ths
    if ( mantissa )
149 85016c98 ths
        return make_float32(
150 85016c98 ths
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
151 85016c98 ths
    else
152 85016c98 ths
        return float32_default_nan;
153 158142c2 bellard
}
154 158142c2 bellard
155 158142c2 bellard
/*----------------------------------------------------------------------------
156 158142c2 bellard
| Takes two single-precision floating-point values `a' and `b', one of which
157 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
158 158142c2 bellard
| signaling NaN, the invalid exception is raised.
159 158142c2 bellard
*----------------------------------------------------------------------------*/
160 158142c2 bellard
161 158142c2 bellard
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
162 158142c2 bellard
{
163 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
164 f090c9d4 pbrook
    bits32 av, bv, res;
165 158142c2 bellard
166 5c7908ed pbrook
    if ( STATUS(default_nan_mode) )
167 5c7908ed pbrook
        return float32_default_nan;
168 5c7908ed pbrook
169 18569871 Peter Maydell
    aIsNaN = float32_is_quiet_nan( a );
170 158142c2 bellard
    aIsSignalingNaN = float32_is_signaling_nan( a );
171 18569871 Peter Maydell
    bIsNaN = float32_is_quiet_nan( b );
172 158142c2 bellard
    bIsSignalingNaN = float32_is_signaling_nan( b );
173 f090c9d4 pbrook
    av = float32_val(a);
174 f090c9d4 pbrook
    bv = float32_val(b);
175 5a6932d5 ths
#if SNAN_BIT_IS_ONE
176 f090c9d4 pbrook
    av &= ~0x00400000;
177 f090c9d4 pbrook
    bv &= ~0x00400000;
178 b645bb48 ths
#else
179 f090c9d4 pbrook
    av |= 0x00400000;
180 f090c9d4 pbrook
    bv |= 0x00400000;
181 b645bb48 ths
#endif
182 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
183 158142c2 bellard
    if ( aIsSignalingNaN ) {
184 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
185 f090c9d4 pbrook
        res = bIsNaN ? bv : av;
186 158142c2 bellard
    }
187 158142c2 bellard
    else if ( aIsNaN ) {
188 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN )
189 f090c9d4 pbrook
            res = av;
190 f090c9d4 pbrook
        else {
191 158142c2 bellard
 returnLargerSignificand:
192 f090c9d4 pbrook
            if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
193 f090c9d4 pbrook
                res = bv;
194 f090c9d4 pbrook
            else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
195 f090c9d4 pbrook
                res = av;
196 f090c9d4 pbrook
            else
197 f090c9d4 pbrook
                res = ( av < bv ) ? av : bv;
198 f090c9d4 pbrook
        }
199 158142c2 bellard
    }
200 158142c2 bellard
    else {
201 f090c9d4 pbrook
        res = bv;
202 158142c2 bellard
    }
203 f090c9d4 pbrook
    return make_float32(res);
204 158142c2 bellard
}
205 158142c2 bellard
206 158142c2 bellard
/*----------------------------------------------------------------------------
207 158142c2 bellard
| The pattern for a default generated double-precision NaN.
208 158142c2 bellard
*----------------------------------------------------------------------------*/
209 85016c98 ths
#if defined(TARGET_SPARC)
210 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
211 990b3e19 Richard Henderson
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
212 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
213 85016c98 ths
#elif defined(TARGET_HPPA)
214 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
215 85016c98 ths
#elif SNAN_BIT_IS_ONE
216 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
217 b645bb48 ths
#else
218 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
219 b645bb48 ths
#endif
220 158142c2 bellard
221 158142c2 bellard
/*----------------------------------------------------------------------------
222 5a6932d5 ths
| Returns 1 if the double-precision floating-point value `a' is a quiet
223 5a6932d5 ths
| NaN; otherwise returns 0.
224 158142c2 bellard
*----------------------------------------------------------------------------*/
225 158142c2 bellard
226 18569871 Peter Maydell
int float64_is_quiet_nan( float64 a_ )
227 158142c2 bellard
{
228 f090c9d4 pbrook
    bits64 a = float64_val(a_);
229 5a6932d5 ths
#if SNAN_BIT_IS_ONE
230 b645bb48 ths
    return
231 b645bb48 ths
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232 b645bb48 ths
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233 b645bb48 ths
#else
234 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
235 b645bb48 ths
#endif
236 158142c2 bellard
}
237 158142c2 bellard
238 158142c2 bellard
/*----------------------------------------------------------------------------
239 158142c2 bellard
| Returns 1 if the double-precision floating-point value `a' is a signaling
240 158142c2 bellard
| NaN; otherwise returns 0.
241 158142c2 bellard
*----------------------------------------------------------------------------*/
242 158142c2 bellard
243 f090c9d4 pbrook
int float64_is_signaling_nan( float64 a_ )
244 158142c2 bellard
{
245 f090c9d4 pbrook
    bits64 a = float64_val(a_);
246 5a6932d5 ths
#if SNAN_BIT_IS_ONE
247 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
248 b645bb48 ths
#else
249 158142c2 bellard
    return
250 158142c2 bellard
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
251 158142c2 bellard
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
252 b645bb48 ths
#endif
253 158142c2 bellard
}
254 158142c2 bellard
255 158142c2 bellard
/*----------------------------------------------------------------------------
256 b408dbde Peter Maydell
| Returns a quiet NaN if the double-precision floating point value `a' is a
257 b408dbde Peter Maydell
| signaling NaN; otherwise returns `a'.
258 b408dbde Peter Maydell
*----------------------------------------------------------------------------*/
259 b408dbde Peter Maydell
260 b408dbde Peter Maydell
float64 float64_maybe_silence_nan( float64 a_ )
261 b408dbde Peter Maydell
{
262 b408dbde Peter Maydell
    if (float64_is_signaling_nan(a_)) {
263 b408dbde Peter Maydell
        bits64 a = float64_val(a_);
264 b408dbde Peter Maydell
#if SNAN_BIT_IS_ONE
265 b408dbde Peter Maydell
        a &= ~LIT64( 0x0008000000000000 );
266 b408dbde Peter Maydell
#else
267 b408dbde Peter Maydell
        a |= LIT64( 0x0008000000000000 );
268 b408dbde Peter Maydell
#endif
269 b408dbde Peter Maydell
        return make_float64(a);
270 b408dbde Peter Maydell
    }
271 b408dbde Peter Maydell
    return a_;
272 b408dbde Peter Maydell
}
273 b408dbde Peter Maydell
274 b408dbde Peter Maydell
/*----------------------------------------------------------------------------
275 158142c2 bellard
| Returns the result of converting the double-precision floating-point NaN
276 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
277 158142c2 bellard
| exception is raised.
278 158142c2 bellard
*----------------------------------------------------------------------------*/
279 158142c2 bellard
280 158142c2 bellard
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
281 158142c2 bellard
{
282 158142c2 bellard
    commonNaNT z;
283 158142c2 bellard
284 158142c2 bellard
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
285 f090c9d4 pbrook
    z.sign = float64_val(a)>>63;
286 158142c2 bellard
    z.low = 0;
287 f090c9d4 pbrook
    z.high = float64_val(a)<<12;
288 158142c2 bellard
    return z;
289 158142c2 bellard
}
290 158142c2 bellard
291 158142c2 bellard
/*----------------------------------------------------------------------------
292 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the double-
293 158142c2 bellard
| precision floating-point format.
294 158142c2 bellard
*----------------------------------------------------------------------------*/
295 158142c2 bellard
296 158142c2 bellard
static float64 commonNaNToFloat64( commonNaNT a )
297 158142c2 bellard
{
298 85016c98 ths
    bits64 mantissa = a.high>>12;
299 85016c98 ths
300 85016c98 ths
    if ( mantissa )
301 85016c98 ths
        return make_float64(
302 85016c98 ths
              ( ( (bits64) a.sign )<<63 )
303 85016c98 ths
            | LIT64( 0x7FF0000000000000 )
304 85016c98 ths
            | ( a.high>>12 ));
305 85016c98 ths
    else
306 85016c98 ths
        return float64_default_nan;
307 158142c2 bellard
}
308 158142c2 bellard
309 158142c2 bellard
/*----------------------------------------------------------------------------
310 158142c2 bellard
| Takes two double-precision floating-point values `a' and `b', one of which
311 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
312 158142c2 bellard
| signaling NaN, the invalid exception is raised.
313 158142c2 bellard
*----------------------------------------------------------------------------*/
314 158142c2 bellard
315 158142c2 bellard
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
316 158142c2 bellard
{
317 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
318 f090c9d4 pbrook
    bits64 av, bv, res;
319 158142c2 bellard
320 5c7908ed pbrook
    if ( STATUS(default_nan_mode) )
321 5c7908ed pbrook
        return float64_default_nan;
322 5c7908ed pbrook
323 18569871 Peter Maydell
    aIsNaN = float64_is_quiet_nan( a );
324 158142c2 bellard
    aIsSignalingNaN = float64_is_signaling_nan( a );
325 18569871 Peter Maydell
    bIsNaN = float64_is_quiet_nan( b );
326 158142c2 bellard
    bIsSignalingNaN = float64_is_signaling_nan( b );
327 f090c9d4 pbrook
    av = float64_val(a);
328 f090c9d4 pbrook
    bv = float64_val(b);
329 5a6932d5 ths
#if SNAN_BIT_IS_ONE
330 f090c9d4 pbrook
    av &= ~LIT64( 0x0008000000000000 );
331 f090c9d4 pbrook
    bv &= ~LIT64( 0x0008000000000000 );
332 b645bb48 ths
#else
333 f090c9d4 pbrook
    av |= LIT64( 0x0008000000000000 );
334 f090c9d4 pbrook
    bv |= LIT64( 0x0008000000000000 );
335 b645bb48 ths
#endif
336 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
337 158142c2 bellard
    if ( aIsSignalingNaN ) {
338 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
339 f090c9d4 pbrook
        res = bIsNaN ? bv : av;
340 158142c2 bellard
    }
341 158142c2 bellard
    else if ( aIsNaN ) {
342 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN )
343 f090c9d4 pbrook
            res = av;
344 f090c9d4 pbrook
        else {
345 158142c2 bellard
 returnLargerSignificand:
346 f090c9d4 pbrook
            if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
347 f090c9d4 pbrook
                res = bv;
348 f090c9d4 pbrook
            else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
349 f090c9d4 pbrook
                res = av;
350 f090c9d4 pbrook
            else
351 f090c9d4 pbrook
                res = ( av < bv ) ? av : bv;
352 f090c9d4 pbrook
        }
353 158142c2 bellard
    }
354 158142c2 bellard
    else {
355 f090c9d4 pbrook
        res = bv;
356 158142c2 bellard
    }
357 f090c9d4 pbrook
    return make_float64(res);
358 158142c2 bellard
}
359 158142c2 bellard
360 158142c2 bellard
#ifdef FLOATX80
361 158142c2 bellard
362 158142c2 bellard
/*----------------------------------------------------------------------------
363 158142c2 bellard
| The pattern for a default generated extended double-precision NaN.  The
364 158142c2 bellard
| `high' and `low' values hold the most- and least-significant bits,
365 158142c2 bellard
| respectively.
366 158142c2 bellard
*----------------------------------------------------------------------------*/
367 5a6932d5 ths
#if SNAN_BIT_IS_ONE
368 5a6932d5 ths
#define floatx80_default_nan_high 0x7FFF
369 5a6932d5 ths
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
370 5a6932d5 ths
#else
371 158142c2 bellard
#define floatx80_default_nan_high 0xFFFF
372 158142c2 bellard
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
373 5a6932d5 ths
#endif
374 158142c2 bellard
375 158142c2 bellard
/*----------------------------------------------------------------------------
376 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
377 5a6932d5 ths
| quiet NaN; otherwise returns 0.
378 158142c2 bellard
*----------------------------------------------------------------------------*/
379 158142c2 bellard
380 18569871 Peter Maydell
int floatx80_is_quiet_nan( floatx80 a )
381 158142c2 bellard
{
382 5a6932d5 ths
#if SNAN_BIT_IS_ONE
383 5a6932d5 ths
    bits64 aLow;
384 158142c2 bellard
385 5a6932d5 ths
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
386 5a6932d5 ths
    return
387 5a6932d5 ths
           ( ( a.high & 0x7FFF ) == 0x7FFF )
388 5a6932d5 ths
        && (bits64) ( aLow<<1 )
389 5a6932d5 ths
        && ( a.low == aLow );
390 5a6932d5 ths
#else
391 158142c2 bellard
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
392 5a6932d5 ths
#endif
393 158142c2 bellard
}
394 158142c2 bellard
395 158142c2 bellard
/*----------------------------------------------------------------------------
396 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
397 158142c2 bellard
| signaling NaN; otherwise returns 0.
398 158142c2 bellard
*----------------------------------------------------------------------------*/
399 158142c2 bellard
400 750afe93 bellard
int floatx80_is_signaling_nan( floatx80 a )
401 158142c2 bellard
{
402 5a6932d5 ths
#if SNAN_BIT_IS_ONE
403 5a6932d5 ths
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
404 5a6932d5 ths
#else
405 158142c2 bellard
    bits64 aLow;
406 158142c2 bellard
407 158142c2 bellard
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
408 158142c2 bellard
    return
409 158142c2 bellard
           ( ( a.high & 0x7FFF ) == 0x7FFF )
410 158142c2 bellard
        && (bits64) ( aLow<<1 )
411 158142c2 bellard
        && ( a.low == aLow );
412 5a6932d5 ths
#endif
413 158142c2 bellard
}
414 158142c2 bellard
415 158142c2 bellard
/*----------------------------------------------------------------------------
416 158142c2 bellard
| Returns the result of converting the extended double-precision floating-
417 158142c2 bellard
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
418 158142c2 bellard
| invalid exception is raised.
419 158142c2 bellard
*----------------------------------------------------------------------------*/
420 158142c2 bellard
421 158142c2 bellard
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
422 158142c2 bellard
{
423 158142c2 bellard
    commonNaNT z;
424 158142c2 bellard
425 158142c2 bellard
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
426 158142c2 bellard
    z.sign = a.high>>15;
427 158142c2 bellard
    z.low = 0;
428 85016c98 ths
    z.high = a.low;
429 158142c2 bellard
    return z;
430 158142c2 bellard
}
431 158142c2 bellard
432 158142c2 bellard
/*----------------------------------------------------------------------------
433 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the extended
434 158142c2 bellard
| double-precision floating-point format.
435 158142c2 bellard
*----------------------------------------------------------------------------*/
436 158142c2 bellard
437 158142c2 bellard
static floatx80 commonNaNToFloatx80( commonNaNT a )
438 158142c2 bellard
{
439 158142c2 bellard
    floatx80 z;
440 158142c2 bellard
441 85016c98 ths
    if (a.high)
442 85016c98 ths
        z.low = a.high;
443 85016c98 ths
    else
444 85016c98 ths
        z.low = floatx80_default_nan_low;
445 158142c2 bellard
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
446 158142c2 bellard
    return z;
447 158142c2 bellard
}
448 158142c2 bellard
449 158142c2 bellard
/*----------------------------------------------------------------------------
450 158142c2 bellard
| Takes two extended double-precision floating-point values `a' and `b', one
451 158142c2 bellard
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
452 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
453 158142c2 bellard
*----------------------------------------------------------------------------*/
454 158142c2 bellard
455 158142c2 bellard
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
456 158142c2 bellard
{
457 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
458 158142c2 bellard
459 5c7908ed pbrook
    if ( STATUS(default_nan_mode) ) {
460 5c7908ed pbrook
        a.low = floatx80_default_nan_low;
461 5c7908ed pbrook
        a.high = floatx80_default_nan_high;
462 5c7908ed pbrook
        return a;
463 5c7908ed pbrook
    }
464 5c7908ed pbrook
465 18569871 Peter Maydell
    aIsNaN = floatx80_is_quiet_nan( a );
466 158142c2 bellard
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
467 18569871 Peter Maydell
    bIsNaN = floatx80_is_quiet_nan( b );
468 158142c2 bellard
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
469 5a6932d5 ths
#if SNAN_BIT_IS_ONE
470 5a6932d5 ths
    a.low &= ~LIT64( 0xC000000000000000 );
471 5a6932d5 ths
    b.low &= ~LIT64( 0xC000000000000000 );
472 5a6932d5 ths
#else
473 158142c2 bellard
    a.low |= LIT64( 0xC000000000000000 );
474 158142c2 bellard
    b.low |= LIT64( 0xC000000000000000 );
475 5a6932d5 ths
#endif
476 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
477 158142c2 bellard
    if ( aIsSignalingNaN ) {
478 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
479 158142c2 bellard
        return bIsNaN ? b : a;
480 158142c2 bellard
    }
481 158142c2 bellard
    else if ( aIsNaN ) {
482 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
483 158142c2 bellard
 returnLargerSignificand:
484 158142c2 bellard
        if ( a.low < b.low ) return b;
485 158142c2 bellard
        if ( b.low < a.low ) return a;
486 158142c2 bellard
        return ( a.high < b.high ) ? a : b;
487 158142c2 bellard
    }
488 158142c2 bellard
    else {
489 158142c2 bellard
        return b;
490 158142c2 bellard
    }
491 158142c2 bellard
}
492 158142c2 bellard
493 158142c2 bellard
#endif
494 158142c2 bellard
495 158142c2 bellard
#ifdef FLOAT128
496 158142c2 bellard
497 158142c2 bellard
/*----------------------------------------------------------------------------
498 158142c2 bellard
| The pattern for a default generated quadruple-precision NaN.  The `high' and
499 158142c2 bellard
| `low' values hold the most- and least-significant bits, respectively.
500 158142c2 bellard
*----------------------------------------------------------------------------*/
501 5a6932d5 ths
#if SNAN_BIT_IS_ONE
502 5a6932d5 ths
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
503 5a6932d5 ths
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
504 5a6932d5 ths
#else
505 158142c2 bellard
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
506 158142c2 bellard
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
507 5a6932d5 ths
#endif
508 158142c2 bellard
509 158142c2 bellard
/*----------------------------------------------------------------------------
510 5a6932d5 ths
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
511 5a6932d5 ths
| NaN; otherwise returns 0.
512 158142c2 bellard
*----------------------------------------------------------------------------*/
513 158142c2 bellard
514 18569871 Peter Maydell
int float128_is_quiet_nan( float128 a )
515 158142c2 bellard
{
516 5a6932d5 ths
#if SNAN_BIT_IS_ONE
517 5a6932d5 ths
    return
518 5a6932d5 ths
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
519 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
520 5a6932d5 ths
#else
521 158142c2 bellard
    return
522 158142c2 bellard
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
523 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
524 5a6932d5 ths
#endif
525 158142c2 bellard
}
526 158142c2 bellard
527 158142c2 bellard
/*----------------------------------------------------------------------------
528 158142c2 bellard
| Returns 1 if the quadruple-precision floating-point value `a' is a
529 158142c2 bellard
| signaling NaN; otherwise returns 0.
530 158142c2 bellard
*----------------------------------------------------------------------------*/
531 158142c2 bellard
532 750afe93 bellard
int float128_is_signaling_nan( float128 a )
533 158142c2 bellard
{
534 5a6932d5 ths
#if SNAN_BIT_IS_ONE
535 5a6932d5 ths
    return
536 5a6932d5 ths
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
537 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
538 5a6932d5 ths
#else
539 158142c2 bellard
    return
540 158142c2 bellard
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
541 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
542 5a6932d5 ths
#endif
543 158142c2 bellard
}
544 158142c2 bellard
545 158142c2 bellard
/*----------------------------------------------------------------------------
546 158142c2 bellard
| Returns the result of converting the quadruple-precision floating-point NaN
547 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
548 158142c2 bellard
| exception is raised.
549 158142c2 bellard
*----------------------------------------------------------------------------*/
550 158142c2 bellard
551 158142c2 bellard
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
552 158142c2 bellard
{
553 158142c2 bellard
    commonNaNT z;
554 158142c2 bellard
555 158142c2 bellard
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
556 158142c2 bellard
    z.sign = a.high>>63;
557 158142c2 bellard
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
558 158142c2 bellard
    return z;
559 158142c2 bellard
}
560 158142c2 bellard
561 158142c2 bellard
/*----------------------------------------------------------------------------
562 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the quadruple-
563 158142c2 bellard
| precision floating-point format.
564 158142c2 bellard
*----------------------------------------------------------------------------*/
565 158142c2 bellard
566 158142c2 bellard
static float128 commonNaNToFloat128( commonNaNT a )
567 158142c2 bellard
{
568 158142c2 bellard
    float128 z;
569 158142c2 bellard
570 158142c2 bellard
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
571 85016c98 ths
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
572 158142c2 bellard
    return z;
573 158142c2 bellard
}
574 158142c2 bellard
575 158142c2 bellard
/*----------------------------------------------------------------------------
576 158142c2 bellard
| Takes two quadruple-precision floating-point values `a' and `b', one of
577 158142c2 bellard
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
578 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
579 158142c2 bellard
*----------------------------------------------------------------------------*/
580 158142c2 bellard
581 158142c2 bellard
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
582 158142c2 bellard
{
583 158142c2 bellard
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
584 158142c2 bellard
585 5c7908ed pbrook
    if ( STATUS(default_nan_mode) ) {
586 5c7908ed pbrook
        a.low = float128_default_nan_low;
587 5c7908ed pbrook
        a.high = float128_default_nan_high;
588 5c7908ed pbrook
        return a;
589 5c7908ed pbrook
    }
590 5c7908ed pbrook
591 18569871 Peter Maydell
    aIsNaN = float128_is_quiet_nan( a );
592 158142c2 bellard
    aIsSignalingNaN = float128_is_signaling_nan( a );
593 18569871 Peter Maydell
    bIsNaN = float128_is_quiet_nan( b );
594 158142c2 bellard
    bIsSignalingNaN = float128_is_signaling_nan( b );
595 5a6932d5 ths
#if SNAN_BIT_IS_ONE
596 5a6932d5 ths
    a.high &= ~LIT64( 0x0000800000000000 );
597 5a6932d5 ths
    b.high &= ~LIT64( 0x0000800000000000 );
598 5a6932d5 ths
#else
599 158142c2 bellard
    a.high |= LIT64( 0x0000800000000000 );
600 158142c2 bellard
    b.high |= LIT64( 0x0000800000000000 );
601 5a6932d5 ths
#endif
602 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
603 158142c2 bellard
    if ( aIsSignalingNaN ) {
604 158142c2 bellard
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
605 158142c2 bellard
        return bIsNaN ? b : a;
606 158142c2 bellard
    }
607 158142c2 bellard
    else if ( aIsNaN ) {
608 70c14705 blueswir1
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
609 158142c2 bellard
 returnLargerSignificand:
610 158142c2 bellard
        if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
611 158142c2 bellard
        if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
612 158142c2 bellard
        return ( a.high < b.high ) ? a : b;
613 158142c2 bellard
    }
614 158142c2 bellard
    else {
615 158142c2 bellard
        return b;
616 158142c2 bellard
    }
617 158142c2 bellard
}
618 158142c2 bellard
619 158142c2 bellard
#endif