Remove building with NOCRYPTO option
[minix3.git] / lib / libc / softfloat / softfloat-specialize
blobf721ddbce5677ee04132e767df009c8ecb3ff7a5
1 /*      $NetBSD: softfloat-specialize,v 1.9 2014/08/10 05:57:31 matt Exp $      */
3 /* This is a derivative work. */
5 /*
6 ===============================================================================
8 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
9 Arithmetic Package, Release 2a.
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'.
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.
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.
32 ===============================================================================
35 #include <signal.h>
36 #include <string.h>
37 #include <unistd.h>
40 -------------------------------------------------------------------------------
41 Underflow tininess-detection mode, statically initialized to default value.
42 (The declaration in `softfloat.h' must match the `int8' type here.)
43 -------------------------------------------------------------------------------
45 #ifdef SOFTFLOAT_FOR_GCC
46 static
47 #endif
48 int8 float_detect_tininess = float_tininess_after_rounding;
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 -------------------------------------------------------------------------------
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 )
69     siginfo_t info;
70     fp_except mask = float_exception_mask;
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
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 #if !defined(__minix)
96 /* LSC FIXME: This kind of remove any interest to the function. We should
97                be using the minix equivalent, or do something appropriate. */
98         sigqueueinfo(getpid(), &info);
99 #endif /* !defined(__minix) */
100     }
102 #undef float_exception_mask
105 -------------------------------------------------------------------------------
106 Internal canonical NaN format.
107 -------------------------------------------------------------------------------
109 typedef struct {
110     flag sign;
111     bits64 high, low;
112 } commonNaNT;
115 -------------------------------------------------------------------------------
116 The pattern for a default generated single-precision NaN.
117 -------------------------------------------------------------------------------
119 #define float32_default_nan 0xFFFFFFFF
122 -------------------------------------------------------------------------------
123 Returns 1 if the single-precision floating-point value `a' is a NaN;
124 otherwise returns 0.
125 -------------------------------------------------------------------------------
127 #ifdef SOFTFLOAT_FOR_GCC
128 static
129 #endif
130 flag float32_is_nan( float32 a )
133     return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) );
138 -------------------------------------------------------------------------------
139 Returns 1 if the single-precision floating-point value `a' is a signaling
140 NaN; otherwise returns 0.
141 -------------------------------------------------------------------------------
143 #if defined(SOFTFLOAT_FOR_GCC) \
144     && !defined(SOFTFLOATAARCH64_FOR_GCC) \
145     && !defined(SOFTFLOATSPARC64_FOR_GCC) \
146     && !defined(SOFTFLOATM68K_FOR_GCC)
147 static
148 #endif
149 flag float32_is_signaling_nan( float32 a )
152     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
157 -------------------------------------------------------------------------------
158 Returns the result of converting the single-precision floating-point NaN
159 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
160 exception is raised.
161 -------------------------------------------------------------------------------
163 static commonNaNT float32ToCommonNaN( float32 a )
165     commonNaNT z;
167     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
168     z.sign = a>>31;
169     z.low = 0;
170     z.high = ( (bits64) a )<<41;
171     return z;
176 -------------------------------------------------------------------------------
177 Returns the result of converting the canonical NaN `a' to the single-
178 precision floating-point format.
179 -------------------------------------------------------------------------------
181 static float32 commonNaNToFloat32( commonNaNT a )
184     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 );
189 -------------------------------------------------------------------------------
190 Takes two single-precision floating-point values `a' and `b', one of which
191 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
192 signaling NaN, the invalid exception is raised.
193 -------------------------------------------------------------------------------
195 static float32 propagateFloat32NaN( float32 a, float32 b )
197     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
199     aIsNaN = float32_is_nan( a );
200     aIsSignalingNaN = float32_is_signaling_nan( a );
201     bIsNaN = float32_is_nan( b );
202     bIsSignalingNaN = float32_is_signaling_nan( b );
203     a |= 0x00400000;
204     b |= 0x00400000;
205     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
206     if ( aIsNaN ) {
207         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
208     }
209     else {
210         return b;
211     }
216 -------------------------------------------------------------------------------
217 The pattern for a default generated double-precision NaN.
218 -------------------------------------------------------------------------------
220 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
223 -------------------------------------------------------------------------------
224 Returns 1 if the double-precision floating-point value `a' is a NaN;
225 otherwise returns 0.
226 -------------------------------------------------------------------------------
228 #ifdef SOFTFLOAT_FOR_GCC
229 static
230 #endif
231 flag float64_is_nan( float64 a )
234     return ( (bits64)LIT64( 0xFFE0000000000000 ) <
235              (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
240 -------------------------------------------------------------------------------
241 Returns 1 if the double-precision floating-point value `a' is a signaling
242 NaN; otherwise returns 0.
243 -------------------------------------------------------------------------------
245 #if defined(SOFTFLOAT_FOR_GCC) \
246     && !defined(SOFTFLOATAARCH64_FOR_GCC) \
247     && !defined(SOFTFLOATSPARC64_FOR_GCC) \
248     && !defined(SOFTFLOATM68K_FOR_GCC)
249 static
250 #endif
251 flag float64_is_signaling_nan( float64 a )
254     return
255            ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
256         && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
261 -------------------------------------------------------------------------------
262 Returns the result of converting the double-precision floating-point NaN
263 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
264 exception is raised.
265 -------------------------------------------------------------------------------
267 static commonNaNT float64ToCommonNaN( float64 a )
269     commonNaNT z;
271     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
272     z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63);
273     z.low = 0;
274     z.high = FLOAT64_DEMANGLE(a)<<12;
275     return z;
280 -------------------------------------------------------------------------------
281 Returns the result of converting the canonical NaN `a' to the double-
282 precision floating-point format.
283 -------------------------------------------------------------------------------
285 static float64 commonNaNToFloat64( commonNaNT a )
288     return FLOAT64_MANGLE(
289         ( ( (bits64) a.sign )<<63 )
290         | LIT64( 0x7FF8000000000000 )
291         | ( a.high>>12 ) );
296 -------------------------------------------------------------------------------
297 Takes two double-precision floating-point values `a' and `b', one of which
298 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
299 signaling NaN, the invalid exception is raised.
300 -------------------------------------------------------------------------------
302 static float64 propagateFloat64NaN( float64 a, float64 b )
304     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
306     aIsNaN = float64_is_nan( a );
307     aIsSignalingNaN = float64_is_signaling_nan( a );
308     bIsNaN = float64_is_nan( b );
309     bIsSignalingNaN = float64_is_signaling_nan( b );
310     a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
311     b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
312     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
313     if ( aIsNaN ) {
314         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
315     }
316     else {
317         return b;
318     }
322 #ifdef FLOATX80
325 -------------------------------------------------------------------------------
326 The pattern for a default generated extended double-precision NaN.  The
327 `high' and `low' values hold the most- and least-significant bits,
328 respectively.
329 -------------------------------------------------------------------------------
331 #define floatx80_default_nan_high 0xFFFF
332 #define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
335 -------------------------------------------------------------------------------
336 Returns 1 if the extended double-precision floating-point value `a' is a
337 NaN; otherwise returns 0.
338 -------------------------------------------------------------------------------
340 flag floatx80_is_nan( floatx80 a )
343     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
348 -------------------------------------------------------------------------------
349 Returns 1 if the extended double-precision floating-point value `a' is a
350 signaling NaN; otherwise returns 0.
351 -------------------------------------------------------------------------------
353 flag floatx80_is_signaling_nan( floatx80 a )
355     bits64 aLow;
357     aLow = a.low & ~ LIT64( 0x4000000000000000 );
358     return
359            ( ( a.high & 0x7FFF ) == 0x7FFF )
360         && (bits64) ( aLow<<1 )
361         && ( a.low == aLow );
366 -------------------------------------------------------------------------------
367 Returns the result of converting the extended double-precision floating-
368 point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
369 invalid exception is raised.
370 -------------------------------------------------------------------------------
372 static commonNaNT floatx80ToCommonNaN( floatx80 a )
374     commonNaNT z;
376     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
377     z.sign = a.high>>15;
378     z.low = 0;
379     z.high = a.low<<1;
380     return z;
385 -------------------------------------------------------------------------------
386 Returns the result of converting the canonical NaN `a' to the extended
387 double-precision floating-point format.
388 -------------------------------------------------------------------------------
390 static floatx80 commonNaNToFloatx80( commonNaNT a )
392     floatx80 z;
394     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
395     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
396     return z;
401 -------------------------------------------------------------------------------
402 Takes two extended double-precision floating-point values `a' and `b', one
403 of which is a NaN, and returns the appropriate NaN result.  If either `a' or
404 `b' is a signaling NaN, the invalid exception is raised.
405 -------------------------------------------------------------------------------
407 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
409     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
411     aIsNaN = floatx80_is_nan( a );
412     aIsSignalingNaN = floatx80_is_signaling_nan( a );
413     bIsNaN = floatx80_is_nan( b );
414     bIsSignalingNaN = floatx80_is_signaling_nan( b );
415     a.low |= LIT64( 0xC000000000000000 );
416     b.low |= LIT64( 0xC000000000000000 );
417     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
418     if ( aIsNaN ) {
419         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
420     }
421     else {
422         return b;
423     }
427 #endif
429 #ifdef FLOAT128
432 -------------------------------------------------------------------------------
433 The pattern for a default generated quadruple-precision NaN.  The `high' and
434 `low' values hold the most- and least-significant bits, respectively.
435 -------------------------------------------------------------------------------
437 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
438 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
441 -------------------------------------------------------------------------------
442 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
443 otherwise returns 0.
444 -------------------------------------------------------------------------------
446 flag float128_is_nan( float128 a )
449     return
450            ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
451         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
456 -------------------------------------------------------------------------------
457 Returns 1 if the quadruple-precision floating-point value `a' is a
458 signaling NaN; otherwise returns 0.
459 -------------------------------------------------------------------------------
461 flag float128_is_signaling_nan( float128 a )
464     return
465            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
466         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
471 -------------------------------------------------------------------------------
472 Returns the result of converting the quadruple-precision floating-point NaN
473 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
474 exception is raised.
475 -------------------------------------------------------------------------------
477 static commonNaNT float128ToCommonNaN( float128 a )
479     commonNaNT z;
481     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
482     z.sign = (flag)(a.high>>63);
483     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
484     return z;
489 -------------------------------------------------------------------------------
490 Returns the result of converting the canonical NaN `a' to the quadruple-
491 precision floating-point format.
492 -------------------------------------------------------------------------------
494 static float128 commonNaNToFloat128( commonNaNT a )
496     float128 z;
498     shift128Right( a.high, a.low, 16, &z.high, &z.low );
499     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
500     return z;
505 -------------------------------------------------------------------------------
506 Takes two quadruple-precision floating-point values `a' and `b', one of
507 which is a NaN, and returns the appropriate NaN result.  If either `a' or
508 `b' is a signaling NaN, the invalid exception is raised.
509 -------------------------------------------------------------------------------
511 static float128 propagateFloat128NaN( float128 a, float128 b )
513     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
515     aIsNaN = float128_is_nan( a );
516     aIsSignalingNaN = float128_is_signaling_nan( a );
517     bIsNaN = float128_is_nan( b );
518     bIsSignalingNaN = float128_is_signaling_nan( b );
519     a.high |= LIT64( 0x0000800000000000 );
520     b.high |= LIT64( 0x0000800000000000 );
521     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
522     if ( aIsNaN ) {
523         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
524     }
525     else {
526         return b;
527     }
531 #endif