1 /* $NetBSD: softfloat-specialize.h,v 1.1 2001/04/26 03:10:47 ross Exp $ */
2 
3 /* This is a derivative work. */
4 
5 /*-
6  * Copyright (c) 2001 The NetBSD Foundation, Inc.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to The NetBSD Foundation
10  * by Ross Harvey.
11  *
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.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42 ===============================================================================
43 
44 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
45 Arithmetic Package, Release 2a.
46 
47 Written by John R. Hauser.  This work was made possible in part by the
48 International Computer Science Institute, located at Suite 600, 1947 Center
49 Street, Berkeley, California 94704.  Funding was partially provided by the
50 National Science Foundation under grant MIP-9311980.  The original version
51 of this code was written as part of a project to build a fixed-point vector
52 processor in collaboration with the University of California at Berkeley,
53 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
54 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
55 arithmetic/SoftFloat.html'.
56 
57 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
58 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
59 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
60 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
61 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
62 
63 Derivative works are acceptable, even for commercial purposes, so long as
64 (1) they include prominent notice that the work is derivative, and (2) they
65 include prominent notice akin to these four paragraphs for those parts of
66 this code that are retained.
67 
68 ===============================================================================
69 */
70 
71 /*
72 -------------------------------------------------------------------------------
73 Underflow tininess-detection mode, statically initialized to default value.
74 -------------------------------------------------------------------------------
75 */
76 
77 /* [ MP safe, does not change dynamically ] */
78 int float_detect_tininess = float_tininess_after_rounding;
79 
80 /*
81 -------------------------------------------------------------------------------
82 Internal canonical NaN format.
83 -------------------------------------------------------------------------------
84 */
85 typedef struct {
86     flag sign;
87     bits64 high, low;
88 } commonNaNT;
89 
90 /*
91 -------------------------------------------------------------------------------
92 The pattern for a default generated single-precision NaN.
93 -------------------------------------------------------------------------------
94 */
95 #define float32_default_nan 0xFFC00000
96 
97 /*
98 -------------------------------------------------------------------------------
99 Returns 1 if the single-precision floating-point value `a' is a NaN;
100 otherwise returns 0.
101 -------------------------------------------------------------------------------
102 */
103 static flag float32_is_nan( float32 a )
104 {
105 
106     return ( 0xFF000000 < (bits32) ( a<<1 ) );
107 
108 }
109 
110 /*
111 -------------------------------------------------------------------------------
112 Returns 1 if the single-precision floating-point value `a' is a signaling
113 NaN; otherwise returns 0.
114 -------------------------------------------------------------------------------
115 */
116 flag float32_is_signaling_nan( float32 a )
117 {
118 
119     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
120 
121 }
122 
123 /*
124 -------------------------------------------------------------------------------
125 Returns the result of converting the single-precision floating-point NaN
126 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
127 exception is raised.
128 -------------------------------------------------------------------------------
129 */
130 static commonNaNT float32ToCommonNaN( float32 a )
131 {
132     commonNaNT z;
133 
134     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
135     z.sign = a>>31;
136     z.low = 0;
137     z.high = ( (bits64) a )<<41;
138     return z;
139 
140 }
141 
142 /*
143 -------------------------------------------------------------------------------
144 Returns the result of converting the canonical NaN `a' to the single-
145 precision floating-point format.
146 -------------------------------------------------------------------------------
147 */
148 static float32 commonNaNToFloat32( commonNaNT a )
149 {
150 
151     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
152 
153 }
154 
155 /*
156 -------------------------------------------------------------------------------
157 Takes two single-precision floating-point values `a' and `b', one of which
158 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
159 signaling NaN, the invalid exception is raised.
160 -------------------------------------------------------------------------------
161 */
162 static float32 propagateFloat32NaN( float32 a, float32 b )
163 {
164     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
165 
166     aIsNaN = float32_is_nan( a );
167     aIsSignalingNaN = float32_is_signaling_nan( a );
168     bIsNaN = float32_is_nan( b );
169     bIsSignalingNaN = float32_is_signaling_nan( b );
170     a |= 0x00400000;
171     b |= 0x00400000;
172     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
173     if ( aIsSignalingNaN ) {
174         if ( bIsSignalingNaN ) goto returnLargerSignificand;
175         return bIsNaN ? b : a;
176     }
177     else if ( aIsNaN ) {
178         if ( bIsSignalingNaN | ! bIsNaN ) return a;
179  returnLargerSignificand:
180         if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
181         if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
182         return ( a < b ) ? a : b;
183     }
184     else {
185         return b;
186     }
187 
188 }
189 
190 
191 /*
192 -------------------------------------------------------------------------------
193 Returns the result of converting the double-precision floating-point NaN
194 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
195 exception is raised.
196 -------------------------------------------------------------------------------
197 */
198 static commonNaNT float64ToCommonNaN( float64 a )
199 {
200     commonNaNT z;
201 
202     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
203     z.sign = a>>63;
204     z.low = 0;
205     z.high = a<<12;
206     return z;
207 
208 }
209 
210 /*
211 -------------------------------------------------------------------------------
212 Returns the result of converting the canonical NaN `a' to the double-
213 precision floating-point format.
214 -------------------------------------------------------------------------------
215 */
216 static float64 commonNaNToFloat64( commonNaNT a )
217 {
218 
219     return
220           ( ( (bits64) a.sign )<<63 )
221         | LIT64( 0x7FF8000000000000 )
222         | ( a.high>>12 );
223 
224 }
225 
226 /*
227 -------------------------------------------------------------------------------
228 Takes two double-precision floating-point values `a' and `b', one of which
229 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
230 signaling NaN, the invalid exception is raised.
231 -------------------------------------------------------------------------------
232 */
233 static float64 propagateFloat64NaN( float64 a, float64 b )
234 {
235     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
236 
237     aIsNaN = float64_is_nan( a );
238     aIsSignalingNaN = float64_is_signaling_nan( a );
239     bIsNaN = float64_is_nan( b );
240     bIsSignalingNaN = float64_is_signaling_nan( b );
241     a |= LIT64( 0x0008000000000000 );
242     b |= LIT64( 0x0008000000000000 );
243     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
244     if ( aIsSignalingNaN ) {
245         if ( bIsSignalingNaN ) goto returnLargerSignificand;
246         return bIsNaN ? b : a;
247     }
248     else if ( aIsNaN ) {
249         if ( bIsSignalingNaN | ! bIsNaN ) return a;
250  returnLargerSignificand:
251         if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
252         if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
253         return ( a < b ) ? a : b;
254     }
255     else {
256         return b;
257     }
258 
259 }
260 
261 #ifdef FLOATX80
262 
263 /*
264 -------------------------------------------------------------------------------
265 The pattern for a default generated extended double-precision NaN.  The
266 `high' and `low' values hold the most- and least-significant bits,
267 respectively.
268 -------------------------------------------------------------------------------
269 */
270 #define floatx80_default_nan_high 0xFFFF
271 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
272 
273 /*
274 -------------------------------------------------------------------------------
275 Returns 1 if the extended double-precision floating-point value `a' is a
276 NaN; otherwise returns 0.
277 -------------------------------------------------------------------------------
278 */
279 static flag floatx80_is_nan( floatx80 a )
280 {
281 
282     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
283 
284 }
285 
286 /*
287 -------------------------------------------------------------------------------
288 Returns 1 if the extended double-precision floating-point value `a' is a
289 signaling NaN; otherwise returns 0.
290 -------------------------------------------------------------------------------
291 */
292 flag floatx80_is_signaling_nan( floatx80 a )
293 {
294     bits64 aLow;
295 
296     aLow = a.low & ~ LIT64( 0x4000000000000000 );
297     return
298            ( ( a.high & 0x7FFF ) == 0x7FFF )
299         && (bits64) ( aLow<<1 )
300         && ( a.low == aLow );
301 
302 }
303 
304 /*
305 -------------------------------------------------------------------------------
306 Returns the result of converting the extended double-precision floating-
307 point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
308 invalid exception is raised.
309 -------------------------------------------------------------------------------
310 */
311 static commonNaNT floatx80ToCommonNaN( floatx80 a )
312 {
313     commonNaNT z;
314 
315     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
316     z.sign = a.high>>15;
317     z.low = 0;
318     z.high = a.low<<1;
319     return z;
320 
321 }
322 
323 /*
324 -------------------------------------------------------------------------------
325 Returns the result of converting the canonical NaN `a' to the extended
326 double-precision floating-point format.
327 -------------------------------------------------------------------------------
328 */
329 static floatx80 commonNaNToFloatx80( commonNaNT a )
330 {
331     floatx80 z;
332 
333     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
334     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
335     return z;
336 
337 }
338 
339 /*
340 -------------------------------------------------------------------------------
341 Takes two extended double-precision floating-point values `a' and `b', one
342 of which is a NaN, and returns the appropriate NaN result.  If either `a' or
343 `b' is a signaling NaN, the invalid exception is raised.
344 -------------------------------------------------------------------------------
345 */
346 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
347 {
348     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
349 
350     aIsNaN = floatx80_is_nan( a );
351     aIsSignalingNaN = floatx80_is_signaling_nan( a );
352     bIsNaN = floatx80_is_nan( b );
353     bIsSignalingNaN = floatx80_is_signaling_nan( b );
354     a.low |= LIT64( 0xC000000000000000 );
355     b.low |= LIT64( 0xC000000000000000 );
356     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
357     if ( aIsSignalingNaN ) {
358         if ( bIsSignalingNaN ) goto returnLargerSignificand;
359         return bIsNaN ? b : a;
360     }
361     else if ( aIsNaN ) {
362         if ( bIsSignalingNaN | ! bIsNaN ) return a;
363  returnLargerSignificand:
364         if ( a.low < b.low ) return b;
365         if ( b.low < a.low ) return a;
366         return ( a.high < b.high ) ? a : b;
367     }
368     else {
369         return b;
370     }
371 
372 }
373 
374 #endif
375 
376 #ifdef FLOAT128
377 
378 /*
379 -------------------------------------------------------------------------------
380 The pattern for a default generated quadruple-precision NaN.  The `high' and
381 `low' values hold the most- and least-significant bits, respectively.
382 -------------------------------------------------------------------------------
383 */
384 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
385 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
386 
387 /*
388 -------------------------------------------------------------------------------
389 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
390 otherwise returns 0.
391 -------------------------------------------------------------------------------
392 */
393 flag float128_is_nan( float128 a )
394 {
395 
396     return
397            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
398         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
399 
400 }
401 
402 /*
403 -------------------------------------------------------------------------------
404 Returns 1 if the quadruple-precision floating-point value `a' is a
405 signaling NaN; otherwise returns 0.
406 -------------------------------------------------------------------------------
407 */
408 flag float128_is_signaling_nan( float128 a )
409 {
410 
411     return
412            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
413         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
414 
415 }
416 
417 /*
418 -------------------------------------------------------------------------------
419 Returns the result of converting the quadruple-precision floating-point NaN
420 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
421 exception is raised.
422 -------------------------------------------------------------------------------
423 */
424 static commonNaNT float128ToCommonNaN( float128 a )
425 {
426     commonNaNT z;
427 
428     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
429     z.sign = a.high>>63;
430     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
431     return z;
432 
433 }
434 
435 /*
436 -------------------------------------------------------------------------------
437 Returns the result of converting the canonical NaN `a' to the quadruple-
438 precision floating-point format.
439 -------------------------------------------------------------------------------
440 */
441 static float128 commonNaNToFloat128( commonNaNT a )
442 {
443     float128 z;
444 
445     shift128Right( a.high, a.low, 16, &z.high, &z.low );
446     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
447     return z;
448 
449 }
450 
451 /*
452 -------------------------------------------------------------------------------
453 Takes two quadruple-precision floating-point values `a' and `b', one of
454 which is a NaN, and returns the appropriate NaN result.  If either `a' or
455 `b' is a signaling NaN, the invalid exception is raised.
456 -------------------------------------------------------------------------------
457 */
458 static float128 propagateFloat128NaN( float128 a, float128 b )
459 {
460     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
461 
462     aIsNaN = float128_is_nan( a );
463     aIsSignalingNaN = float128_is_signaling_nan( a );
464     bIsNaN = float128_is_nan( b );
465     bIsSignalingNaN = float128_is_signaling_nan( b );
466     a.high |= LIT64( 0x0000800000000000 );
467     b.high |= LIT64( 0x0000800000000000 );
468     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
469     if ( aIsSignalingNaN ) {
470         if ( bIsSignalingNaN ) goto returnLargerSignificand;
471         return bIsNaN ? b : a;
472     }
473     else if ( aIsNaN ) {
474         if ( bIsSignalingNaN | ! bIsNaN ) return a;
475  returnLargerSignificand:
476         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
477         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
478         return ( a.high < b.high ) ? a : b;
479     }
480     else {
481         return b;
482     }
483 
484 }
485 
486 #endif
487 
488