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 */
float32_is_nan(float32 a)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 */
float32_is_signaling_nan(float32 a)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 */
float32ToCommonNaN(float32 a)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 */
commonNaNToFloat32(commonNaNT a)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 */
propagateFloat32NaN(float32 a,float32 b)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 */
float64ToCommonNaN(float64 a)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 */
commonNaNToFloat64(commonNaNT a)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 */
propagateFloat64NaN(float64 a,float64 b)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 */
floatx80_is_nan(floatx80 a)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 */
floatx80_is_signaling_nan(floatx80 a)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 */
floatx80ToCommonNaN(floatx80 a)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 */
commonNaNToFloatx80(commonNaNT a)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 */
propagateFloatx80NaN(floatx80 a,floatx80 b)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 */
float128_is_nan(float128 a)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 */
float128_is_signaling_nan(float128 a)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 */
float128ToCommonNaN(float128 a)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 */
commonNaNToFloat128(commonNaNT a)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 */
propagateFloat128NaN(float128 a,float128 b)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