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