softfloat-specialize revision 1.6 1 /* $NetBSD: softfloat-specialize,v 1.6 2011/03/06 10:27:37 martin 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 #define float_exception_mask _softfloat_float_exception_mask
60 #endif
61 fp_except float_exception_mask = 0;
62 void float_raise( fp_except flags )
63 {
64 siginfo_t info;
65
66 float_exception_flags |= flags;
67
68 if ( flags & float_exception_mask ) {
69 memset(&info, 0, sizeof info);
70 info.si_signo = SIGFPE;
71 info.si_pid = getpid();
72 info.si_uid = geteuid();
73 if (flags & float_flag_underflow)
74 info.si_code = FPE_FLTUND;
75 else if (flags & float_flag_overflow)
76 info.si_code = FPE_FLTOVF;
77 else if (flags & float_flag_divbyzero)
78 info.si_code = FPE_FLTDIV;
79 else if (flags & float_flag_invalid)
80 info.si_code = FPE_FLTINV;
81 else if (flags & float_flag_inexact)
82 info.si_code = FPE_FLTRES;
83 sigqueueinfo(getpid(), &info);
84 }
85 }
86 #undef float_exception_mask
87
88 /*
89 -------------------------------------------------------------------------------
90 Internal canonical NaN format.
91 -------------------------------------------------------------------------------
92 */
93 typedef struct {
94 flag sign;
95 bits64 high, low;
96 } commonNaNT;
97
98 /*
99 -------------------------------------------------------------------------------
100 The pattern for a default generated single-precision NaN.
101 -------------------------------------------------------------------------------
102 */
103 #define float32_default_nan 0xFFFFFFFF
104
105 /*
106 -------------------------------------------------------------------------------
107 Returns 1 if the single-precision floating-point value `a' is a NaN;
108 otherwise returns 0.
109 -------------------------------------------------------------------------------
110 */
111 #ifdef SOFTFLOAT_FOR_GCC
112 static
113 #endif
114 flag float32_is_nan( float32 a )
115 {
116
117 return ( 0xFF000000 < (bits32) ( a<<1 ) );
118
119 }
120
121 /*
122 -------------------------------------------------------------------------------
123 Returns 1 if the single-precision floating-point value `a' is a signaling
124 NaN; otherwise returns 0.
125 -------------------------------------------------------------------------------
126 */
127 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
128 !defined(SOFTFLOAT_M68K_FOR_GCC)
129 static
130 #endif
131 flag float32_is_signaling_nan( float32 a )
132 {
133
134 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
135
136 }
137
138 /*
139 -------------------------------------------------------------------------------
140 Returns the result of converting the single-precision floating-point NaN
141 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
142 exception is raised.
143 -------------------------------------------------------------------------------
144 */
145 static commonNaNT float32ToCommonNaN( float32 a )
146 {
147 commonNaNT z;
148
149 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
150 z.sign = a>>31;
151 z.low = 0;
152 z.high = ( (bits64) a )<<41;
153 return z;
154
155 }
156
157 /*
158 -------------------------------------------------------------------------------
159 Returns the result of converting the canonical NaN `a' to the single-
160 precision floating-point format.
161 -------------------------------------------------------------------------------
162 */
163 static float32 commonNaNToFloat32( commonNaNT a )
164 {
165
166 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
167
168 }
169
170 /*
171 -------------------------------------------------------------------------------
172 Takes two single-precision floating-point values `a' and `b', one of which
173 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
174 signaling NaN, the invalid exception is raised.
175 -------------------------------------------------------------------------------
176 */
177 static float32 propagateFloat32NaN( float32 a, float32 b )
178 {
179 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
180
181 aIsNaN = float32_is_nan( a );
182 aIsSignalingNaN = float32_is_signaling_nan( a );
183 bIsNaN = float32_is_nan( b );
184 bIsSignalingNaN = float32_is_signaling_nan( b );
185 a |= 0x00400000;
186 b |= 0x00400000;
187 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
188 if ( aIsNaN ) {
189 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
190 }
191 else {
192 return b;
193 }
194
195 }
196
197 /*
198 -------------------------------------------------------------------------------
199 The pattern for a default generated double-precision NaN.
200 -------------------------------------------------------------------------------
201 */
202 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
203
204 /*
205 -------------------------------------------------------------------------------
206 Returns 1 if the double-precision floating-point value `a' is a NaN;
207 otherwise returns 0.
208 -------------------------------------------------------------------------------
209 */
210 #ifdef SOFTFLOAT_FOR_GCC
211 static
212 #endif
213 flag float64_is_nan( float64 a )
214 {
215
216 return ( LIT64( 0xFFE0000000000000 ) <
217 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
218
219 }
220
221 /*
222 -------------------------------------------------------------------------------
223 Returns 1 if the double-precision floating-point value `a' is a signaling
224 NaN; otherwise returns 0.
225 -------------------------------------------------------------------------------
226 */
227 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
228 !defined(SOFTFLOATM68K_FOR_GCC)
229 static
230 #endif
231 flag float64_is_signaling_nan( float64 a )
232 {
233
234 return
235 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
236 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
237
238 }
239
240 /*
241 -------------------------------------------------------------------------------
242 Returns the result of converting the double-precision floating-point NaN
243 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
244 exception is raised.
245 -------------------------------------------------------------------------------
246 */
247 static commonNaNT float64ToCommonNaN( float64 a )
248 {
249 commonNaNT z;
250
251 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
252 z.sign = FLOAT64_DEMANGLE(a)>>63;
253 z.low = 0;
254 z.high = FLOAT64_DEMANGLE(a)<<12;
255 return z;
256
257 }
258
259 /*
260 -------------------------------------------------------------------------------
261 Returns the result of converting the canonical NaN `a' to the double-
262 precision floating-point format.
263 -------------------------------------------------------------------------------
264 */
265 static float64 commonNaNToFloat64( commonNaNT a )
266 {
267
268 return FLOAT64_MANGLE(
269 ( ( (bits64) a.sign )<<63 )
270 | LIT64( 0x7FF8000000000000 )
271 | ( a.high>>12 ) );
272
273 }
274
275 /*
276 -------------------------------------------------------------------------------
277 Takes two double-precision floating-point values `a' and `b', one of which
278 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
279 signaling NaN, the invalid exception is raised.
280 -------------------------------------------------------------------------------
281 */
282 static float64 propagateFloat64NaN( float64 a, float64 b )
283 {
284 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
285
286 aIsNaN = float64_is_nan( a );
287 aIsSignalingNaN = float64_is_signaling_nan( a );
288 bIsNaN = float64_is_nan( b );
289 bIsSignalingNaN = float64_is_signaling_nan( b );
290 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
291 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
292 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
293 if ( aIsNaN ) {
294 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
295 }
296 else {
297 return b;
298 }
299
300 }
301
302 #ifdef FLOATX80
303
304 /*
305 -------------------------------------------------------------------------------
306 The pattern for a default generated extended double-precision NaN. The
307 `high' and `low' values hold the most- and least-significant bits,
308 respectively.
309 -------------------------------------------------------------------------------
310 */
311 #define floatx80_default_nan_high 0xFFFF
312 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
313
314 /*
315 -------------------------------------------------------------------------------
316 Returns 1 if the extended double-precision floating-point value `a' is a
317 NaN; otherwise returns 0.
318 -------------------------------------------------------------------------------
319 */
320 flag floatx80_is_nan( floatx80 a )
321 {
322
323 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
324
325 }
326
327 /*
328 -------------------------------------------------------------------------------
329 Returns 1 if the extended double-precision floating-point value `a' is a
330 signaling NaN; otherwise returns 0.
331 -------------------------------------------------------------------------------
332 */
333 flag floatx80_is_signaling_nan( floatx80 a )
334 {
335 bits64 aLow;
336
337 aLow = a.low & ~ LIT64( 0x4000000000000000 );
338 return
339 ( ( a.high & 0x7FFF ) == 0x7FFF )
340 && (bits64) ( aLow<<1 )
341 && ( a.low == aLow );
342
343 }
344
345 /*
346 -------------------------------------------------------------------------------
347 Returns the result of converting the extended double-precision floating-
348 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
349 invalid exception is raised.
350 -------------------------------------------------------------------------------
351 */
352 static commonNaNT floatx80ToCommonNaN( floatx80 a )
353 {
354 commonNaNT z;
355
356 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
357 z.sign = a.high>>15;
358 z.low = 0;
359 z.high = a.low<<1;
360 return z;
361
362 }
363
364 /*
365 -------------------------------------------------------------------------------
366 Returns the result of converting the canonical NaN `a' to the extended
367 double-precision floating-point format.
368 -------------------------------------------------------------------------------
369 */
370 static floatx80 commonNaNToFloatx80( commonNaNT a )
371 {
372 floatx80 z;
373
374 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
375 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
376 return z;
377
378 }
379
380 /*
381 -------------------------------------------------------------------------------
382 Takes two extended double-precision floating-point values `a' and `b', one
383 of which is a NaN, and returns the appropriate NaN result. If either `a' or
384 `b' is a signaling NaN, the invalid exception is raised.
385 -------------------------------------------------------------------------------
386 */
387 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
388 {
389 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
390
391 aIsNaN = floatx80_is_nan( a );
392 aIsSignalingNaN = floatx80_is_signaling_nan( a );
393 bIsNaN = floatx80_is_nan( b );
394 bIsSignalingNaN = floatx80_is_signaling_nan( b );
395 a.low |= LIT64( 0xC000000000000000 );
396 b.low |= LIT64( 0xC000000000000000 );
397 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
398 if ( aIsNaN ) {
399 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
400 }
401 else {
402 return b;
403 }
404
405 }
406
407 #endif
408
409 #ifdef FLOAT128
410
411 /*
412 -------------------------------------------------------------------------------
413 The pattern for a default generated quadruple-precision NaN. The `high' and
414 `low' values hold the most- and least-significant bits, respectively.
415 -------------------------------------------------------------------------------
416 */
417 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
418 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
419
420 /*
421 -------------------------------------------------------------------------------
422 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
423 otherwise returns 0.
424 -------------------------------------------------------------------------------
425 */
426 flag float128_is_nan( float128 a )
427 {
428
429 return
430 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
431 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
432
433 }
434
435 /*
436 -------------------------------------------------------------------------------
437 Returns 1 if the quadruple-precision floating-point value `a' is a
438 signaling NaN; otherwise returns 0.
439 -------------------------------------------------------------------------------
440 */
441 flag float128_is_signaling_nan( float128 a )
442 {
443
444 return
445 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
446 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
447
448 }
449
450 /*
451 -------------------------------------------------------------------------------
452 Returns the result of converting the quadruple-precision floating-point NaN
453 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
454 exception is raised.
455 -------------------------------------------------------------------------------
456 */
457 static commonNaNT float128ToCommonNaN( float128 a )
458 {
459 commonNaNT z;
460
461 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
462 z.sign = a.high>>63;
463 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
464 return z;
465
466 }
467
468 /*
469 -------------------------------------------------------------------------------
470 Returns the result of converting the canonical NaN `a' to the quadruple-
471 precision floating-point format.
472 -------------------------------------------------------------------------------
473 */
474 static float128 commonNaNToFloat128( commonNaNT a )
475 {
476 float128 z;
477
478 shift128Right( a.high, a.low, 16, &z.high, &z.low );
479 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
480 return z;
481
482 }
483
484 /*
485 -------------------------------------------------------------------------------
486 Takes two quadruple-precision floating-point values `a' and `b', one of
487 which is a NaN, and returns the appropriate NaN result. If either `a' or
488 `b' is a signaling NaN, the invalid exception is raised.
489 -------------------------------------------------------------------------------
490 */
491 static float128 propagateFloat128NaN( float128 a, float128 b )
492 {
493 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
494
495 aIsNaN = float128_is_nan( a );
496 aIsSignalingNaN = float128_is_signaling_nan( a );
497 bIsNaN = float128_is_nan( b );
498 bIsSignalingNaN = float128_is_signaling_nan( b );
499 a.high |= LIT64( 0x0000800000000000 );
500 b.high |= LIT64( 0x0000800000000000 );
501 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
502 if ( aIsNaN ) {
503 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
504 }
505 else {
506 return b;
507 }
508
509 }
510
511 #endif
512
513