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