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