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