Fix iovec for the case with invalid elements (Lauro Ramos Venancio).
[qemu/sh4.git] / fpu / softfloat-specialize.h
blobe7f09d1a9bf1c517b100622f6b50aa9ba5fcc288
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 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
34 #define SNAN_BIT_IS_ONE 1
35 #else
36 #define SNAN_BIT_IS_ONE 0
37 #endif
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 )
48 STATUS(float_exception_flags) |= flags;
51 /*----------------------------------------------------------------------------
52 | Internal canonical NaN format.
53 *----------------------------------------------------------------------------*/
54 typedef struct {
55 flag sign;
56 bits64 high, low;
57 } commonNaNT;
59 /*----------------------------------------------------------------------------
60 | The pattern for a default generated single-precision NaN.
61 *----------------------------------------------------------------------------*/
62 #if defined(TARGET_SPARC)
63 #define float32_default_nan make_float32(0x7FFFFFFF)
64 #elif defined(TARGET_POWERPC)
65 #define float32_default_nan make_float32(0x7FC00000)
66 #elif defined(TARGET_HPPA)
67 #define float32_default_nan make_float32(0x7FA00000)
68 #elif SNAN_BIT_IS_ONE
69 #define float32_default_nan make_float32(0x7FBFFFFF)
70 #else
71 #define float32_default_nan make_float32(0xFFC00000)
72 #endif
74 /*----------------------------------------------------------------------------
75 | Returns 1 if the single-precision floating-point value `a' is a quiet
76 | NaN; otherwise returns 0.
77 *----------------------------------------------------------------------------*/
79 int float32_is_nan( float32 a_ )
81 uint32_t a = float32_val(a_);
82 #if SNAN_BIT_IS_ONE
83 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
84 #else
85 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
86 #endif
89 /*----------------------------------------------------------------------------
90 | Returns 1 if the single-precision floating-point value `a' is a signaling
91 | NaN; otherwise returns 0.
92 *----------------------------------------------------------------------------*/
94 int float32_is_signaling_nan( float32 a_ )
96 uint32_t a = float32_val(a_);
97 #if SNAN_BIT_IS_ONE
98 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
99 #else
100 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
101 #endif
104 /*----------------------------------------------------------------------------
105 | Returns the result of converting the single-precision floating-point NaN
106 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
107 | exception is raised.
108 *----------------------------------------------------------------------------*/
110 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
112 commonNaNT z;
114 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
115 z.sign = float32_val(a)>>31;
116 z.low = 0;
117 z.high = ( (bits64) float32_val(a) )<<41;
118 return z;
121 /*----------------------------------------------------------------------------
122 | Returns the result of converting the canonical NaN `a' to the single-
123 | precision floating-point format.
124 *----------------------------------------------------------------------------*/
126 static float32 commonNaNToFloat32( commonNaNT a )
128 bits32 mantissa = a.high>>41;
129 if ( mantissa )
130 return make_float32(
131 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
132 else
133 return float32_default_nan;
136 /*----------------------------------------------------------------------------
137 | Takes two single-precision floating-point values `a' and `b', one of which
138 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
139 | signaling NaN, the invalid exception is raised.
140 *----------------------------------------------------------------------------*/
142 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
144 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
145 bits32 av, bv, res;
147 aIsNaN = float32_is_nan( a );
148 aIsSignalingNaN = float32_is_signaling_nan( a );
149 bIsNaN = float32_is_nan( b );
150 bIsSignalingNaN = float32_is_signaling_nan( b );
151 av = float32_val(a);
152 bv = float32_val(b);
153 #if SNAN_BIT_IS_ONE
154 av &= ~0x00400000;
155 bv &= ~0x00400000;
156 #else
157 av |= 0x00400000;
158 bv |= 0x00400000;
159 #endif
160 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
161 if ( aIsSignalingNaN ) {
162 if ( bIsSignalingNaN ) goto returnLargerSignificand;
163 res = bIsNaN ? bv : av;
165 else if ( aIsNaN ) {
166 if ( bIsSignalingNaN | ! bIsNaN )
167 res = av;
168 else {
169 returnLargerSignificand:
170 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
171 res = bv;
172 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
173 res = av;
174 else
175 res = ( av < bv ) ? av : bv;
178 else {
179 res = bv;
181 return make_float32(res);
184 /*----------------------------------------------------------------------------
185 | The pattern for a default generated double-precision NaN.
186 *----------------------------------------------------------------------------*/
187 #if defined(TARGET_SPARC)
188 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
189 #elif defined(TARGET_POWERPC)
190 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
191 #elif defined(TARGET_HPPA)
192 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
193 #elif SNAN_BIT_IS_ONE
194 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
195 #else
196 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
197 #endif
199 /*----------------------------------------------------------------------------
200 | Returns 1 if the double-precision floating-point value `a' is a quiet
201 | NaN; otherwise returns 0.
202 *----------------------------------------------------------------------------*/
204 int float64_is_nan( float64 a_ )
206 bits64 a = float64_val(a_);
207 #if SNAN_BIT_IS_ONE
208 return
209 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
210 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
211 #else
212 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
213 #endif
216 /*----------------------------------------------------------------------------
217 | Returns 1 if the double-precision floating-point value `a' is a signaling
218 | NaN; otherwise returns 0.
219 *----------------------------------------------------------------------------*/
221 int float64_is_signaling_nan( float64 a_ )
223 bits64 a = float64_val(a_);
224 #if SNAN_BIT_IS_ONE
225 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
226 #else
227 return
228 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
229 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
230 #endif
233 /*----------------------------------------------------------------------------
234 | Returns the result of converting the double-precision floating-point NaN
235 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
236 | exception is raised.
237 *----------------------------------------------------------------------------*/
239 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
241 commonNaNT z;
243 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
244 z.sign = float64_val(a)>>63;
245 z.low = 0;
246 z.high = float64_val(a)<<12;
247 return z;
250 /*----------------------------------------------------------------------------
251 | Returns the result of converting the canonical NaN `a' to the double-
252 | precision floating-point format.
253 *----------------------------------------------------------------------------*/
255 static float64 commonNaNToFloat64( commonNaNT a )
257 bits64 mantissa = a.high>>12;
259 if ( mantissa )
260 return make_float64(
261 ( ( (bits64) a.sign )<<63 )
262 | LIT64( 0x7FF0000000000000 )
263 | ( a.high>>12 ));
264 else
265 return float64_default_nan;
268 /*----------------------------------------------------------------------------
269 | Takes two double-precision floating-point values `a' and `b', one of which
270 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
271 | signaling NaN, the invalid exception is raised.
272 *----------------------------------------------------------------------------*/
274 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
276 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
277 bits64 av, bv, res;
279 aIsNaN = float64_is_nan( a );
280 aIsSignalingNaN = float64_is_signaling_nan( a );
281 bIsNaN = float64_is_nan( b );
282 bIsSignalingNaN = float64_is_signaling_nan( b );
283 av = float64_val(a);
284 bv = float64_val(b);
285 #if SNAN_BIT_IS_ONE
286 av &= ~LIT64( 0x0008000000000000 );
287 bv &= ~LIT64( 0x0008000000000000 );
288 #else
289 av |= LIT64( 0x0008000000000000 );
290 bv |= LIT64( 0x0008000000000000 );
291 #endif
292 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
293 if ( aIsSignalingNaN ) {
294 if ( bIsSignalingNaN ) goto returnLargerSignificand;
295 res = bIsNaN ? bv : av;
297 else if ( aIsNaN ) {
298 if ( bIsSignalingNaN | ! bIsNaN )
299 res = av;
300 else {
301 returnLargerSignificand:
302 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
303 res = bv;
304 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
305 res = av;
306 else
307 res = ( av < bv ) ? av : bv;
310 else {
311 res = bv;
313 return make_float64(res);
316 #ifdef FLOATX80
318 /*----------------------------------------------------------------------------
319 | The pattern for a default generated extended double-precision NaN. The
320 | `high' and `low' values hold the most- and least-significant bits,
321 | respectively.
322 *----------------------------------------------------------------------------*/
323 #if SNAN_BIT_IS_ONE
324 #define floatx80_default_nan_high 0x7FFF
325 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
326 #else
327 #define floatx80_default_nan_high 0xFFFF
328 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
329 #endif
331 /*----------------------------------------------------------------------------
332 | Returns 1 if the extended double-precision floating-point value `a' is a
333 | quiet NaN; otherwise returns 0.
334 *----------------------------------------------------------------------------*/
336 int floatx80_is_nan( floatx80 a )
338 #if SNAN_BIT_IS_ONE
339 bits64 aLow;
341 aLow = a.low & ~ LIT64( 0x4000000000000000 );
342 return
343 ( ( a.high & 0x7FFF ) == 0x7FFF )
344 && (bits64) ( aLow<<1 )
345 && ( a.low == aLow );
346 #else
347 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
348 #endif
351 /*----------------------------------------------------------------------------
352 | Returns 1 if the extended double-precision floating-point value `a' is a
353 | signaling NaN; otherwise returns 0.
354 *----------------------------------------------------------------------------*/
356 int floatx80_is_signaling_nan( floatx80 a )
358 #if SNAN_BIT_IS_ONE
359 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
360 #else
361 bits64 aLow;
363 aLow = a.low & ~ LIT64( 0x4000000000000000 );
364 return
365 ( ( a.high & 0x7FFF ) == 0x7FFF )
366 && (bits64) ( aLow<<1 )
367 && ( a.low == aLow );
368 #endif
371 /*----------------------------------------------------------------------------
372 | Returns the result of converting the extended double-precision floating-
373 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
374 | invalid exception is raised.
375 *----------------------------------------------------------------------------*/
377 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
379 commonNaNT z;
381 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
382 z.sign = a.high>>15;
383 z.low = 0;
384 z.high = a.low;
385 return z;
388 /*----------------------------------------------------------------------------
389 | Returns the result of converting the canonical NaN `a' to the extended
390 | double-precision floating-point format.
391 *----------------------------------------------------------------------------*/
393 static floatx80 commonNaNToFloatx80( commonNaNT a )
395 floatx80 z;
397 if (a.high)
398 z.low = a.high;
399 else
400 z.low = floatx80_default_nan_low;
401 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
402 return z;
405 /*----------------------------------------------------------------------------
406 | Takes two extended double-precision floating-point values `a' and `b', one
407 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
408 | `b' is a signaling NaN, the invalid exception is raised.
409 *----------------------------------------------------------------------------*/
411 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
413 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
415 aIsNaN = floatx80_is_nan( a );
416 aIsSignalingNaN = floatx80_is_signaling_nan( a );
417 bIsNaN = floatx80_is_nan( b );
418 bIsSignalingNaN = floatx80_is_signaling_nan( b );
419 #if SNAN_BIT_IS_ONE
420 a.low &= ~LIT64( 0xC000000000000000 );
421 b.low &= ~LIT64( 0xC000000000000000 );
422 #else
423 a.low |= LIT64( 0xC000000000000000 );
424 b.low |= LIT64( 0xC000000000000000 );
425 #endif
426 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
427 if ( aIsSignalingNaN ) {
428 if ( bIsSignalingNaN ) goto returnLargerSignificand;
429 return bIsNaN ? b : a;
431 else if ( aIsNaN ) {
432 if ( bIsSignalingNaN | ! bIsNaN ) return a;
433 returnLargerSignificand:
434 if ( a.low < b.low ) return b;
435 if ( b.low < a.low ) return a;
436 return ( a.high < b.high ) ? a : b;
438 else {
439 return b;
443 #endif
445 #ifdef FLOAT128
447 /*----------------------------------------------------------------------------
448 | The pattern for a default generated quadruple-precision NaN. The `high' and
449 | `low' values hold the most- and least-significant bits, respectively.
450 *----------------------------------------------------------------------------*/
451 #if SNAN_BIT_IS_ONE
452 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
453 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
454 #else
455 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
456 #define float128_default_nan_low LIT64( 0x0000000000000000 )
457 #endif
459 /*----------------------------------------------------------------------------
460 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
461 | NaN; otherwise returns 0.
462 *----------------------------------------------------------------------------*/
464 int float128_is_nan( float128 a )
466 #if SNAN_BIT_IS_ONE
467 return
468 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
469 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
470 #else
471 return
472 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
473 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
474 #endif
477 /*----------------------------------------------------------------------------
478 | Returns 1 if the quadruple-precision floating-point value `a' is a
479 | signaling NaN; otherwise returns 0.
480 *----------------------------------------------------------------------------*/
482 int float128_is_signaling_nan( float128 a )
484 #if SNAN_BIT_IS_ONE
485 return
486 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
487 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
488 #else
489 return
490 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
491 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
492 #endif
495 /*----------------------------------------------------------------------------
496 | Returns the result of converting the quadruple-precision floating-point NaN
497 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
498 | exception is raised.
499 *----------------------------------------------------------------------------*/
501 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
503 commonNaNT z;
505 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
506 z.sign = a.high>>63;
507 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
508 return z;
511 /*----------------------------------------------------------------------------
512 | Returns the result of converting the canonical NaN `a' to the quadruple-
513 | precision floating-point format.
514 *----------------------------------------------------------------------------*/
516 static float128 commonNaNToFloat128( commonNaNT a )
518 float128 z;
520 shift128Right( a.high, a.low, 16, &z.high, &z.low );
521 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
522 return z;
525 /*----------------------------------------------------------------------------
526 | Takes two quadruple-precision floating-point values `a' and `b', one of
527 | which is a NaN, and returns the appropriate NaN result. If either `a' or
528 | `b' is a signaling NaN, the invalid exception is raised.
529 *----------------------------------------------------------------------------*/
531 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
533 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
535 aIsNaN = float128_is_nan( a );
536 aIsSignalingNaN = float128_is_signaling_nan( a );
537 bIsNaN = float128_is_nan( b );
538 bIsSignalingNaN = float128_is_signaling_nan( b );
539 #if SNAN_BIT_IS_ONE
540 a.high &= ~LIT64( 0x0000800000000000 );
541 b.high &= ~LIT64( 0x0000800000000000 );
542 #else
543 a.high |= LIT64( 0x0000800000000000 );
544 b.high |= LIT64( 0x0000800000000000 );
545 #endif
546 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
547 if ( aIsSignalingNaN ) {
548 if ( bIsSignalingNaN ) goto returnLargerSignificand;
549 return bIsNaN ? b : a;
551 else if ( aIsNaN ) {
552 if ( bIsSignalingNaN | ! bIsNaN ) return a;
553 returnLargerSignificand:
554 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
555 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
556 return ( a.high < b.high ) ? a : b;
558 else {
559 return b;
563 #endif