ColdFire target.
[qemu] / fpu / softfloat-specialize.h
1
2 /*============================================================================
3
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2b.
6
7 Written by John R. Hauser.  This work was made possible in part by the
8 International Computer Science Institute, located at Suite 600, 1947 Center
9 Street, Berkeley, California 94704.  Funding was partially provided by the
10 National Science Foundation under grant MIP-9311980.  The original version
11 of this code was written as part of a project to build a fixed-point vector
12 processor in collaboration with the University of California at Berkeley,
13 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15 arithmetic/SoftFloat.html'.
16
17 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19 RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25
26 Derivative works are acceptable, even for commercial purposes, so long as
27 (1) the source code for the derivative work includes prominent notice that
28 the work is derivative, and (2) the source code includes prominent notice with
29 these four paragraphs for those parts of this code that are retained.
30
31 =============================================================================*/
32
33 /*----------------------------------------------------------------------------
34 | Underflow tininess-detection mode, statically initialized to default value.
35 | (The declaration in `softfloat.h' must match the `int8' type here.)
36 *----------------------------------------------------------------------------*/
37 int8 float_detect_tininess = float_tininess_after_rounding;
38
39 /*----------------------------------------------------------------------------
40 | Raises the exceptions specified by `flags'.  Floating-point traps can be
41 | defined here if desired.  It is currently not possible for such a trap
42 | to substitute a result value.  If traps are not implemented, this routine
43 | should be simply `float_exception_flags |= flags;'.
44 *----------------------------------------------------------------------------*/
45
46 void float_raise( int8 flags STATUS_PARAM )
47 {
48
49     STATUS(float_exception_flags) |= flags;
50
51 }
52
53 /*----------------------------------------------------------------------------
54 | Internal canonical NaN format.
55 *----------------------------------------------------------------------------*/
56 typedef struct {
57     flag sign;
58     bits64 high, low;
59 } commonNaNT;
60
61 /*----------------------------------------------------------------------------
62 | The pattern for a default generated single-precision NaN.
63 *----------------------------------------------------------------------------*/
64 #define float32_default_nan 0xFFC00000
65
66 /*----------------------------------------------------------------------------
67 | Returns 1 if the single-precision floating-point value `a' is a NaN;
68 | otherwise returns 0.
69 *----------------------------------------------------------------------------*/
70
71 flag float32_is_nan( float32 a )
72 {
73
74     return ( 0xFF000000 < (bits32) ( a<<1 ) );
75
76 }
77
78 /*----------------------------------------------------------------------------
79 | Returns 1 if the single-precision floating-point value `a' is a signaling
80 | NaN; otherwise returns 0.
81 *----------------------------------------------------------------------------*/
82
83 flag float32_is_signaling_nan( float32 a )
84 {
85
86     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
87
88 }
89
90 /*----------------------------------------------------------------------------
91 | Returns the result of converting the single-precision floating-point NaN
92 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
93 | exception is raised.
94 *----------------------------------------------------------------------------*/
95
96 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
97 {
98     commonNaNT z;
99
100     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
101     z.sign = a>>31;
102     z.low = 0;
103     z.high = ( (bits64) a )<<41;
104     return z;
105
106 }
107
108 /*----------------------------------------------------------------------------
109 | Returns the result of converting the canonical NaN `a' to the single-
110 | precision floating-point format.
111 *----------------------------------------------------------------------------*/
112
113 static float32 commonNaNToFloat32( commonNaNT a )
114 {
115
116     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
117
118 }
119
120 /*----------------------------------------------------------------------------
121 | Takes two single-precision floating-point values `a' and `b', one of which
122 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
123 | signaling NaN, the invalid exception is raised.
124 *----------------------------------------------------------------------------*/
125
126 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
127 {
128     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
129
130     aIsNaN = float32_is_nan( a );
131     aIsSignalingNaN = float32_is_signaling_nan( a );
132     bIsNaN = float32_is_nan( b );
133     bIsSignalingNaN = float32_is_signaling_nan( b );
134     a |= 0x00400000;
135     b |= 0x00400000;
136     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
137     if ( aIsSignalingNaN ) {
138         if ( bIsSignalingNaN ) goto returnLargerSignificand;
139         return bIsNaN ? b : a;
140     }
141     else if ( aIsNaN ) {
142         if ( bIsSignalingNaN | ! bIsNaN ) return a;
143  returnLargerSignificand:
144         if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
145         if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
146         return ( a < b ) ? a : b;
147     }
148     else {
149         return b;
150     }
151
152 }
153
154 /*----------------------------------------------------------------------------
155 | The pattern for a default generated double-precision NaN.
156 *----------------------------------------------------------------------------*/
157 #define float64_default_nan LIT64( 0xFFF8000000000000 )
158
159 /*----------------------------------------------------------------------------
160 | Returns 1 if the double-precision floating-point value `a' is a NaN;
161 | otherwise returns 0.
162 *----------------------------------------------------------------------------*/
163
164 flag float64_is_nan( float64 a )
165 {
166
167     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
168
169 }
170
171 /*----------------------------------------------------------------------------
172 | Returns 1 if the double-precision floating-point value `a' is a signaling
173 | NaN; otherwise returns 0.
174 *----------------------------------------------------------------------------*/
175
176 flag float64_is_signaling_nan( float64 a )
177 {
178
179     return
180            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
181         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
182
183 }
184
185 /*----------------------------------------------------------------------------
186 | Returns the result of converting the double-precision floating-point NaN
187 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
188 | exception is raised.
189 *----------------------------------------------------------------------------*/
190
191 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
192 {
193     commonNaNT z;
194
195     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
196     z.sign = a>>63;
197     z.low = 0;
198     z.high = a<<12;
199     return z;
200
201 }
202
203 /*----------------------------------------------------------------------------
204 | Returns the result of converting the canonical NaN `a' to the double-
205 | precision floating-point format.
206 *----------------------------------------------------------------------------*/
207
208 static float64 commonNaNToFloat64( commonNaNT a )
209 {
210
211     return
212           ( ( (bits64) a.sign )<<63 )
213         | LIT64( 0x7FF8000000000000 )
214         | ( a.high>>12 );
215
216 }
217
218 /*----------------------------------------------------------------------------
219 | Takes two double-precision floating-point values `a' and `b', one of which
220 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
221 | signaling NaN, the invalid exception is raised.
222 *----------------------------------------------------------------------------*/
223
224 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
225 {
226     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
227
228     aIsNaN = float64_is_nan( a );
229     aIsSignalingNaN = float64_is_signaling_nan( a );
230     bIsNaN = float64_is_nan( b );
231     bIsSignalingNaN = float64_is_signaling_nan( b );
232     a |= LIT64( 0x0008000000000000 );
233     b |= LIT64( 0x0008000000000000 );
234     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
235     if ( aIsSignalingNaN ) {
236         if ( bIsSignalingNaN ) goto returnLargerSignificand;
237         return bIsNaN ? b : a;
238     }
239     else if ( aIsNaN ) {
240         if ( bIsSignalingNaN | ! bIsNaN ) return a;
241  returnLargerSignificand:
242         if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
243         if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
244         return ( a < b ) ? a : b;
245     }
246     else {
247         return b;
248     }
249
250 }
251
252 #ifdef FLOATX80
253
254 /*----------------------------------------------------------------------------
255 | The pattern for a default generated extended double-precision NaN.  The
256 | `high' and `low' values hold the most- and least-significant bits,
257 | respectively.
258 *----------------------------------------------------------------------------*/
259 #define floatx80_default_nan_high 0xFFFF
260 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
261
262 /*----------------------------------------------------------------------------
263 | Returns 1 if the extended double-precision floating-point value `a' is a
264 | NaN; otherwise returns 0.
265 *----------------------------------------------------------------------------*/
266
267 flag floatx80_is_nan( floatx80 a )
268 {
269
270     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
271
272 }
273
274 /*----------------------------------------------------------------------------
275 | Returns 1 if the extended double-precision floating-point value `a' is a
276 | signaling NaN; otherwise returns 0.
277 *----------------------------------------------------------------------------*/
278
279 flag floatx80_is_signaling_nan( floatx80 a )
280 {
281     bits64 aLow;
282
283     aLow = a.low & ~ LIT64( 0x4000000000000000 );
284     return
285            ( ( a.high & 0x7FFF ) == 0x7FFF )
286         && (bits64) ( aLow<<1 )
287         && ( a.low == aLow );
288
289 }
290
291 /*----------------------------------------------------------------------------
292 | Returns the result of converting the extended double-precision floating-
293 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
294 | invalid exception is raised.
295 *----------------------------------------------------------------------------*/
296
297 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
298 {
299     commonNaNT z;
300
301     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
302     z.sign = a.high>>15;
303     z.low = 0;
304     z.high = a.low<<1;
305     return z;
306
307 }
308
309 /*----------------------------------------------------------------------------
310 | Returns the result of converting the canonical NaN `a' to the extended
311 | double-precision floating-point format.
312 *----------------------------------------------------------------------------*/
313
314 static floatx80 commonNaNToFloatx80( commonNaNT a )
315 {
316     floatx80 z;
317
318     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
319     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
320     return z;
321
322 }
323
324 /*----------------------------------------------------------------------------
325 | Takes two extended double-precision floating-point values `a' and `b', one
326 | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
327 | `b' is a signaling NaN, the invalid exception is raised.
328 *----------------------------------------------------------------------------*/
329
330 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
331 {
332     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
333
334     aIsNaN = floatx80_is_nan( a );
335     aIsSignalingNaN = floatx80_is_signaling_nan( a );
336     bIsNaN = floatx80_is_nan( b );
337     bIsSignalingNaN = floatx80_is_signaling_nan( b );
338     a.low |= LIT64( 0xC000000000000000 );
339     b.low |= LIT64( 0xC000000000000000 );
340     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
341     if ( aIsSignalingNaN ) {
342         if ( bIsSignalingNaN ) goto returnLargerSignificand;
343         return bIsNaN ? b : a;
344     }
345     else if ( aIsNaN ) {
346         if ( bIsSignalingNaN | ! bIsNaN ) return a;
347  returnLargerSignificand:
348         if ( a.low < b.low ) return b;
349         if ( b.low < a.low ) return a;
350         return ( a.high < b.high ) ? a : b;
351     }
352     else {
353         return b;
354     }
355
356 }
357
358 #endif
359
360 #ifdef FLOAT128
361
362 /*----------------------------------------------------------------------------
363 | The pattern for a default generated quadruple-precision NaN.  The `high' and
364 | `low' values hold the most- and least-significant bits, respectively.
365 *----------------------------------------------------------------------------*/
366 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
367 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
368
369 /*----------------------------------------------------------------------------
370 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
371 | otherwise returns 0.
372 *----------------------------------------------------------------------------*/
373
374 flag float128_is_nan( float128 a )
375 {
376
377     return
378            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
379         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
380
381 }
382
383 /*----------------------------------------------------------------------------
384 | Returns 1 if the quadruple-precision floating-point value `a' is a
385 | signaling NaN; otherwise returns 0.
386 *----------------------------------------------------------------------------*/
387
388 flag float128_is_signaling_nan( float128 a )
389 {
390
391     return
392            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
393         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
394
395 }
396
397 /*----------------------------------------------------------------------------
398 | Returns the result of converting the quadruple-precision floating-point NaN
399 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
400 | exception is raised.
401 *----------------------------------------------------------------------------*/
402
403 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
404 {
405     commonNaNT z;
406
407     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
408     z.sign = a.high>>63;
409     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
410     return z;
411
412 }
413
414 /*----------------------------------------------------------------------------
415 | Returns the result of converting the canonical NaN `a' to the quadruple-
416 | precision floating-point format.
417 *----------------------------------------------------------------------------*/
418
419 static float128 commonNaNToFloat128( commonNaNT a )
420 {
421     float128 z;
422
423     shift128Right( a.high, a.low, 16, &z.high, &z.low );
424     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
425     return z;
426
427 }
428
429 /*----------------------------------------------------------------------------
430 | Takes two quadruple-precision floating-point values `a' and `b', one of
431 | which is a NaN, and returns the appropriate NaN result.  If either `a' or
432 | `b' is a signaling NaN, the invalid exception is raised.
433 *----------------------------------------------------------------------------*/
434
435 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
436 {
437     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
438
439     aIsNaN = float128_is_nan( a );
440     aIsSignalingNaN = float128_is_signaling_nan( a );
441     bIsNaN = float128_is_nan( b );
442     bIsSignalingNaN = float128_is_signaling_nan( b );
443     a.high |= LIT64( 0x0000800000000000 );
444     b.high |= LIT64( 0x0000800000000000 );
445     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
446     if ( aIsSignalingNaN ) {
447         if ( bIsSignalingNaN ) goto returnLargerSignificand;
448         return bIsNaN ? b : a;
449     }
450     else if ( aIsNaN ) {
451         if ( bIsSignalingNaN | ! bIsNaN ) return a;
452  returnLargerSignificand:
453         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
454         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
455         return ( a.high < b.high ) ? a : b;
456     }
457     else {
458         return b;
459     }
460
461 }
462
463 #endif
464