Add new command line option for controlling shadow cache size
[qemu-kvm/fedora.git] / fpu / softfloat-specialize.h
blob2802eaa8d9c4008ae236883285c23a8b33d0c448
2 /*============================================================================
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2b.
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'.
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.
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.
31 =============================================================================*/
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;
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 *----------------------------------------------------------------------------*/
46 void float_raise( int8 flags STATUS_PARAM )
49 STATUS(float_exception_flags) |= flags;
53 /*----------------------------------------------------------------------------
54 | Internal canonical NaN format.
55 *----------------------------------------------------------------------------*/
56 typedef struct {
57 flag sign;
58 bits64 high, low;
59 } commonNaNT;
61 /*----------------------------------------------------------------------------
62 | The pattern for a default generated single-precision NaN.
63 *----------------------------------------------------------------------------*/
64 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
65 #define float32_default_nan 0xFF800000
66 #else
67 #define float32_default_nan 0xFFC00000
68 #endif
70 /*----------------------------------------------------------------------------
71 | Returns 1 if the single-precision floating-point value `a' is a NaN;
72 | otherwise returns 0.
73 *----------------------------------------------------------------------------*/
75 int float32_is_nan( float32 a )
77 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
78 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
79 #else
80 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
81 #endif
84 /*----------------------------------------------------------------------------
85 | Returns 1 if the single-precision floating-point value `a' is a signaling
86 | NaN; otherwise returns 0.
87 *----------------------------------------------------------------------------*/
89 int float32_is_signaling_nan( float32 a )
91 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
92 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
93 #else
94 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
95 #endif
98 /*----------------------------------------------------------------------------
99 | Returns the result of converting the single-precision floating-point NaN
100 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
101 | exception is raised.
102 *----------------------------------------------------------------------------*/
104 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
106 commonNaNT z;
108 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
109 z.sign = a>>31;
110 z.low = 0;
111 z.high = ( (bits64) a )<<41;
112 return z;
116 /*----------------------------------------------------------------------------
117 | Returns the result of converting the canonical NaN `a' to the single-
118 | precision floating-point format.
119 *----------------------------------------------------------------------------*/
121 static float32 commonNaNToFloat32( commonNaNT a )
124 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
128 /*----------------------------------------------------------------------------
129 | Takes two single-precision floating-point values `a' and `b', one of which
130 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
131 | signaling NaN, the invalid exception is raised.
132 *----------------------------------------------------------------------------*/
134 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
136 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
138 aIsNaN = float32_is_nan( a );
139 aIsSignalingNaN = float32_is_signaling_nan( a );
140 bIsNaN = float32_is_nan( b );
141 bIsSignalingNaN = float32_is_signaling_nan( b );
142 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
143 a &= ~0x00400000;
144 b &= ~0x00400000;
145 #else
146 a |= 0x00400000;
147 b |= 0x00400000;
148 #endif
149 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
150 if ( aIsSignalingNaN ) {
151 if ( bIsSignalingNaN ) goto returnLargerSignificand;
152 return bIsNaN ? b : a;
154 else if ( aIsNaN ) {
155 if ( bIsSignalingNaN | ! bIsNaN ) return a;
156 returnLargerSignificand:
157 if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
158 if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
159 return ( a < b ) ? a : b;
161 else {
162 return b;
167 /*----------------------------------------------------------------------------
168 | The pattern for a default generated double-precision NaN.
169 *----------------------------------------------------------------------------*/
170 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
171 #define float64_default_nan LIT64( 0xFFF0000000000000 )
172 #else
173 #define float64_default_nan LIT64( 0xFFF8000000000000 )
174 #endif
176 /*----------------------------------------------------------------------------
177 | Returns 1 if the double-precision floating-point value `a' is a NaN;
178 | otherwise returns 0.
179 *----------------------------------------------------------------------------*/
181 int float64_is_nan( float64 a )
183 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
184 return
185 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
186 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
187 #else
188 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
189 #endif
192 /*----------------------------------------------------------------------------
193 | Returns 1 if the double-precision floating-point value `a' is a signaling
194 | NaN; otherwise returns 0.
195 *----------------------------------------------------------------------------*/
197 int float64_is_signaling_nan( float64 a )
199 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
200 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
201 #else
202 return
203 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
204 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
205 #endif
208 /*----------------------------------------------------------------------------
209 | Returns the result of converting the double-precision floating-point NaN
210 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
211 | exception is raised.
212 *----------------------------------------------------------------------------*/
214 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
216 commonNaNT z;
218 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
219 z.sign = a>>63;
220 z.low = 0;
221 z.high = a<<12;
222 return z;
226 /*----------------------------------------------------------------------------
227 | Returns the result of converting the canonical NaN `a' to the double-
228 | precision floating-point format.
229 *----------------------------------------------------------------------------*/
231 static float64 commonNaNToFloat64( commonNaNT a )
234 return
235 ( ( (bits64) a.sign )<<63 )
236 | LIT64( 0x7FF8000000000000 )
237 | ( a.high>>12 );
241 /*----------------------------------------------------------------------------
242 | Takes two double-precision floating-point values `a' and `b', one of which
243 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
244 | signaling NaN, the invalid exception is raised.
245 *----------------------------------------------------------------------------*/
247 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
249 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
251 aIsNaN = float64_is_nan( a );
252 aIsSignalingNaN = float64_is_signaling_nan( a );
253 bIsNaN = float64_is_nan( b );
254 bIsSignalingNaN = float64_is_signaling_nan( b );
255 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
256 a &= ~LIT64( 0x0008000000000000 );
257 b &= ~LIT64( 0x0008000000000000 );
258 #else
259 a |= LIT64( 0x0008000000000000 );
260 b |= LIT64( 0x0008000000000000 );
261 #endif
262 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
263 if ( aIsSignalingNaN ) {
264 if ( bIsSignalingNaN ) goto returnLargerSignificand;
265 return bIsNaN ? b : a;
267 else if ( aIsNaN ) {
268 if ( bIsSignalingNaN | ! bIsNaN ) return a;
269 returnLargerSignificand:
270 if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
271 if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
272 return ( a < b ) ? a : b;
274 else {
275 return b;
280 #ifdef FLOATX80
282 /*----------------------------------------------------------------------------
283 | The pattern for a default generated extended double-precision NaN. The
284 | `high' and `low' values hold the most- and least-significant bits,
285 | respectively.
286 *----------------------------------------------------------------------------*/
287 #define floatx80_default_nan_high 0xFFFF
288 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
290 /*----------------------------------------------------------------------------
291 | Returns 1 if the extended double-precision floating-point value `a' is a
292 | NaN; otherwise returns 0.
293 *----------------------------------------------------------------------------*/
295 int floatx80_is_nan( floatx80 a )
298 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
302 /*----------------------------------------------------------------------------
303 | Returns 1 if the extended double-precision floating-point value `a' is a
304 | signaling NaN; otherwise returns 0.
305 *----------------------------------------------------------------------------*/
307 int floatx80_is_signaling_nan( floatx80 a )
309 bits64 aLow;
311 aLow = a.low & ~ LIT64( 0x4000000000000000 );
312 return
313 ( ( a.high & 0x7FFF ) == 0x7FFF )
314 && (bits64) ( aLow<<1 )
315 && ( a.low == aLow );
319 /*----------------------------------------------------------------------------
320 | Returns the result of converting the extended double-precision floating-
321 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
322 | invalid exception is raised.
323 *----------------------------------------------------------------------------*/
325 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
327 commonNaNT z;
329 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
330 z.sign = a.high>>15;
331 z.low = 0;
332 z.high = a.low<<1;
333 return z;
337 /*----------------------------------------------------------------------------
338 | Returns the result of converting the canonical NaN `a' to the extended
339 | double-precision floating-point format.
340 *----------------------------------------------------------------------------*/
342 static floatx80 commonNaNToFloatx80( commonNaNT a )
344 floatx80 z;
346 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
347 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
348 return z;
352 /*----------------------------------------------------------------------------
353 | Takes two extended double-precision floating-point values `a' and `b', one
354 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
355 | `b' is a signaling NaN, the invalid exception is raised.
356 *----------------------------------------------------------------------------*/
358 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
360 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
362 aIsNaN = floatx80_is_nan( a );
363 aIsSignalingNaN = floatx80_is_signaling_nan( a );
364 bIsNaN = floatx80_is_nan( b );
365 bIsSignalingNaN = floatx80_is_signaling_nan( b );
366 a.low |= LIT64( 0xC000000000000000 );
367 b.low |= LIT64( 0xC000000000000000 );
368 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
369 if ( aIsSignalingNaN ) {
370 if ( bIsSignalingNaN ) goto returnLargerSignificand;
371 return bIsNaN ? b : a;
373 else if ( aIsNaN ) {
374 if ( bIsSignalingNaN | ! bIsNaN ) return a;
375 returnLargerSignificand:
376 if ( a.low < b.low ) return b;
377 if ( b.low < a.low ) return a;
378 return ( a.high < b.high ) ? a : b;
380 else {
381 return b;
386 #endif
388 #ifdef FLOAT128
390 /*----------------------------------------------------------------------------
391 | The pattern for a default generated quadruple-precision NaN. The `high' and
392 | `low' values hold the most- and least-significant bits, respectively.
393 *----------------------------------------------------------------------------*/
394 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
395 #define float128_default_nan_low LIT64( 0x0000000000000000 )
397 /*----------------------------------------------------------------------------
398 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
399 | otherwise returns 0.
400 *----------------------------------------------------------------------------*/
402 int float128_is_nan( float128 a )
405 return
406 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
407 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
411 /*----------------------------------------------------------------------------
412 | Returns 1 if the quadruple-precision floating-point value `a' is a
413 | signaling NaN; otherwise returns 0.
414 *----------------------------------------------------------------------------*/
416 int float128_is_signaling_nan( float128 a )
419 return
420 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
421 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
425 /*----------------------------------------------------------------------------
426 | Returns the result of converting the quadruple-precision floating-point NaN
427 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
428 | exception is raised.
429 *----------------------------------------------------------------------------*/
431 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
433 commonNaNT z;
435 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
436 z.sign = a.high>>63;
437 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
438 return z;
442 /*----------------------------------------------------------------------------
443 | Returns the result of converting the canonical NaN `a' to the quadruple-
444 | precision floating-point format.
445 *----------------------------------------------------------------------------*/
447 static float128 commonNaNToFloat128( commonNaNT a )
449 float128 z;
451 shift128Right( a.high, a.low, 16, &z.high, &z.low );
452 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
453 return z;
457 /*----------------------------------------------------------------------------
458 | Takes two quadruple-precision floating-point values `a' and `b', one of
459 | which is a NaN, and returns the appropriate NaN result. If either `a' or
460 | `b' is a signaling NaN, the invalid exception is raised.
461 *----------------------------------------------------------------------------*/
463 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
465 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
467 aIsNaN = float128_is_nan( a );
468 aIsSignalingNaN = float128_is_signaling_nan( a );
469 bIsNaN = float128_is_nan( b );
470 bIsSignalingNaN = float128_is_signaling_nan( b );
471 a.high |= LIT64( 0x0000800000000000 );
472 b.high |= LIT64( 0x0000800000000000 );
473 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
474 if ( aIsSignalingNaN ) {
475 if ( bIsSignalingNaN ) goto returnLargerSignificand;
476 return bIsNaN ? b : a;
478 else if ( aIsNaN ) {
479 if ( bIsSignalingNaN | ! bIsNaN ) return a;
480 returnLargerSignificand:
481 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
482 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
483 return ( a.high < b.high ) ? a : b;
485 else {
486 return b;
491 #endif