Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / lib / libkern / softfloat-specialize.h
blobdf0aaff18117b384ace8a16cd18f4f1408d2fe33
1 /* $NetBSD: softfloat-specialize.h,v 1.1 2001/04/26 03:10:47 ross Exp $ */
3 /* This is a derivative work. */
5 /*-
6 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * All rights reserved.
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Ross Harvey.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
35 ===============================================================================
37 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
38 Arithmetic Package, Release 2a.
40 Written by John R. Hauser. This work was made possible in part by the
41 International Computer Science Institute, located at Suite 600, 1947 Center
42 Street, Berkeley, California 94704. Funding was partially provided by the
43 National Science Foundation under grant MIP-9311980. The original version
44 of this code was written as part of a project to build a fixed-point vector
45 processor in collaboration with the University of California at Berkeley,
46 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
47 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
48 arithmetic/SoftFloat.html'.
50 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
51 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
52 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
53 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
54 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
56 Derivative works are acceptable, even for commercial purposes, so long as
57 (1) they include prominent notice that the work is derivative, and (2) they
58 include prominent notice akin to these four paragraphs for those parts of
59 this code that are retained.
61 ===============================================================================
65 -------------------------------------------------------------------------------
66 Underflow tininess-detection mode, statically initialized to default value.
67 -------------------------------------------------------------------------------
70 /* [ MP safe, does not change dynamically ] */
71 int float_detect_tininess = float_tininess_after_rounding;
74 -------------------------------------------------------------------------------
75 Internal canonical NaN format.
76 -------------------------------------------------------------------------------
78 typedef struct {
79 flag sign;
80 bits64 high, low;
81 } commonNaNT;
84 -------------------------------------------------------------------------------
85 The pattern for a default generated single-precision NaN.
86 -------------------------------------------------------------------------------
88 #define float32_default_nan 0xFFC00000
91 -------------------------------------------------------------------------------
92 Returns 1 if the single-precision floating-point value `a' is a NaN;
93 otherwise returns 0.
94 -------------------------------------------------------------------------------
96 static flag float32_is_nan( float32 a )
99 return ( 0xFF000000 < (bits32) ( a<<1 ) );
104 -------------------------------------------------------------------------------
105 Returns 1 if the single-precision floating-point value `a' is a signaling
106 NaN; otherwise returns 0.
107 -------------------------------------------------------------------------------
109 flag float32_is_signaling_nan( float32 a )
112 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
117 -------------------------------------------------------------------------------
118 Returns the result of converting the single-precision floating-point NaN
119 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
120 exception is raised.
121 -------------------------------------------------------------------------------
123 static commonNaNT float32ToCommonNaN( float32 a )
125 commonNaNT z;
127 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
128 z.sign = a>>31;
129 z.low = 0;
130 z.high = ( (bits64) a )<<41;
131 return z;
136 -------------------------------------------------------------------------------
137 Returns the result of converting the canonical NaN `a' to the single-
138 precision floating-point format.
139 -------------------------------------------------------------------------------
141 static float32 commonNaNToFloat32( commonNaNT a )
144 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
149 -------------------------------------------------------------------------------
150 Takes two single-precision floating-point values `a' and `b', one of which
151 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
152 signaling NaN, the invalid exception is raised.
153 -------------------------------------------------------------------------------
155 static float32 propagateFloat32NaN( float32 a, float32 b )
157 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
159 aIsNaN = float32_is_nan( a );
160 aIsSignalingNaN = float32_is_signaling_nan( a );
161 bIsNaN = float32_is_nan( b );
162 bIsSignalingNaN = float32_is_signaling_nan( b );
163 a |= 0x00400000;
164 b |= 0x00400000;
165 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
166 if ( aIsSignalingNaN ) {
167 if ( bIsSignalingNaN ) goto returnLargerSignificand;
168 return bIsNaN ? b : a;
170 else if ( aIsNaN ) {
171 if ( bIsSignalingNaN | ! bIsNaN ) return a;
172 returnLargerSignificand:
173 if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
174 if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
175 return ( a < b ) ? a : b;
177 else {
178 return b;
185 -------------------------------------------------------------------------------
186 Returns the result of converting the double-precision floating-point NaN
187 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
188 exception is raised.
189 -------------------------------------------------------------------------------
191 static commonNaNT float64ToCommonNaN( float64 a )
193 commonNaNT z;
195 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
196 z.sign = a>>63;
197 z.low = 0;
198 z.high = a<<12;
199 return z;
204 -------------------------------------------------------------------------------
205 Returns the result of converting the canonical NaN `a' to the double-
206 precision floating-point format.
207 -------------------------------------------------------------------------------
209 static float64 commonNaNToFloat64( commonNaNT a )
212 return
213 ( ( (bits64) a.sign )<<63 )
214 | LIT64( 0x7FF8000000000000 )
215 | ( a.high>>12 );
220 -------------------------------------------------------------------------------
221 Takes two double-precision floating-point values `a' and `b', one of which
222 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
223 signaling NaN, the invalid exception is raised.
224 -------------------------------------------------------------------------------
226 static float64 propagateFloat64NaN( float64 a, float64 b )
228 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
230 aIsNaN = float64_is_nan( a );
231 aIsSignalingNaN = float64_is_signaling_nan( a );
232 bIsNaN = float64_is_nan( b );
233 bIsSignalingNaN = float64_is_signaling_nan( b );
234 a |= LIT64( 0x0008000000000000 );
235 b |= LIT64( 0x0008000000000000 );
236 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
237 if ( aIsSignalingNaN ) {
238 if ( bIsSignalingNaN ) goto returnLargerSignificand;
239 return bIsNaN ? b : a;
241 else if ( aIsNaN ) {
242 if ( bIsSignalingNaN | ! bIsNaN ) return a;
243 returnLargerSignificand:
244 if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
245 if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
246 return ( a < b ) ? a : b;
248 else {
249 return b;
254 #ifdef FLOATX80
257 -------------------------------------------------------------------------------
258 The pattern for a default generated extended double-precision NaN. The
259 `high' and `low' values hold the most- and least-significant bits,
260 respectively.
261 -------------------------------------------------------------------------------
263 #define floatx80_default_nan_high 0xFFFF
264 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
267 -------------------------------------------------------------------------------
268 Returns 1 if the extended double-precision floating-point value `a' is a
269 NaN; otherwise returns 0.
270 -------------------------------------------------------------------------------
272 static flag floatx80_is_nan( floatx80 a )
275 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
280 -------------------------------------------------------------------------------
281 Returns 1 if the extended double-precision floating-point value `a' is a
282 signaling NaN; otherwise returns 0.
283 -------------------------------------------------------------------------------
285 flag floatx80_is_signaling_nan( floatx80 a )
287 bits64 aLow;
289 aLow = a.low & ~ LIT64( 0x4000000000000000 );
290 return
291 ( ( a.high & 0x7FFF ) == 0x7FFF )
292 && (bits64) ( aLow<<1 )
293 && ( a.low == aLow );
298 -------------------------------------------------------------------------------
299 Returns the result of converting the extended double-precision floating-
300 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
301 invalid exception is raised.
302 -------------------------------------------------------------------------------
304 static commonNaNT floatx80ToCommonNaN( floatx80 a )
306 commonNaNT z;
308 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
309 z.sign = a.high>>15;
310 z.low = 0;
311 z.high = a.low<<1;
312 return z;
317 -------------------------------------------------------------------------------
318 Returns the result of converting the canonical NaN `a' to the extended
319 double-precision floating-point format.
320 -------------------------------------------------------------------------------
322 static floatx80 commonNaNToFloatx80( commonNaNT a )
324 floatx80 z;
326 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
327 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
328 return z;
333 -------------------------------------------------------------------------------
334 Takes two extended double-precision floating-point values `a' and `b', one
335 of which is a NaN, and returns the appropriate NaN result. If either `a' or
336 `b' is a signaling NaN, the invalid exception is raised.
337 -------------------------------------------------------------------------------
339 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
341 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
343 aIsNaN = floatx80_is_nan( a );
344 aIsSignalingNaN = floatx80_is_signaling_nan( a );
345 bIsNaN = floatx80_is_nan( b );
346 bIsSignalingNaN = floatx80_is_signaling_nan( b );
347 a.low |= LIT64( 0xC000000000000000 );
348 b.low |= LIT64( 0xC000000000000000 );
349 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
350 if ( aIsSignalingNaN ) {
351 if ( bIsSignalingNaN ) goto returnLargerSignificand;
352 return bIsNaN ? b : a;
354 else if ( aIsNaN ) {
355 if ( bIsSignalingNaN | ! bIsNaN ) return a;
356 returnLargerSignificand:
357 if ( a.low < b.low ) return b;
358 if ( b.low < a.low ) return a;
359 return ( a.high < b.high ) ? a : b;
361 else {
362 return b;
367 #endif
369 #ifdef FLOAT128
372 -------------------------------------------------------------------------------
373 The pattern for a default generated quadruple-precision NaN. The `high' and
374 `low' values hold the most- and least-significant bits, respectively.
375 -------------------------------------------------------------------------------
377 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
378 #define float128_default_nan_low LIT64( 0x0000000000000000 )
381 -------------------------------------------------------------------------------
382 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
383 otherwise returns 0.
384 -------------------------------------------------------------------------------
386 flag float128_is_nan( float128 a )
389 return
390 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
391 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
396 -------------------------------------------------------------------------------
397 Returns 1 if the quadruple-precision floating-point value `a' is a
398 signaling NaN; otherwise returns 0.
399 -------------------------------------------------------------------------------
401 flag float128_is_signaling_nan( float128 a )
404 return
405 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
406 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
411 -------------------------------------------------------------------------------
412 Returns the result of converting the quadruple-precision floating-point NaN
413 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
414 exception is raised.
415 -------------------------------------------------------------------------------
417 static commonNaNT float128ToCommonNaN( float128 a )
419 commonNaNT z;
421 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
422 z.sign = a.high>>63;
423 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
424 return z;
429 -------------------------------------------------------------------------------
430 Returns the result of converting the canonical NaN `a' to the quadruple-
431 precision floating-point format.
432 -------------------------------------------------------------------------------
434 static float128 commonNaNToFloat128( commonNaNT a )
436 float128 z;
438 shift128Right( a.high, a.low, 16, &z.high, &z.low );
439 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
440 return z;
445 -------------------------------------------------------------------------------
446 Takes two quadruple-precision floating-point values `a' and `b', one of
447 which is a NaN, and returns the appropriate NaN result. If either `a' or
448 `b' is a signaling NaN, the invalid exception is raised.
449 -------------------------------------------------------------------------------
451 static float128 propagateFloat128NaN( float128 a, float128 b )
453 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
455 aIsNaN = float128_is_nan( a );
456 aIsSignalingNaN = float128_is_signaling_nan( a );
457 bIsNaN = float128_is_nan( b );
458 bIsSignalingNaN = float128_is_signaling_nan( b );
459 a.high |= LIT64( 0x0000800000000000 );
460 b.high |= LIT64( 0x0000800000000000 );
461 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
462 if ( aIsSignalingNaN ) {
463 if ( bIsSignalingNaN ) goto returnLargerSignificand;
464 return bIsNaN ? b : a;
466 else if ( aIsNaN ) {
467 if ( bIsSignalingNaN | ! bIsNaN ) return a;
468 returnLargerSignificand:
469 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
470 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
471 return ( a.high < b.high ) ? a : b;
473 else {
474 return b;
479 #endif