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
Cache object: e8bb272f6628940b34ca55778631e6bd
|