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