softfloat-specialize.h revision 1.3 1 1.3 thorpej /* $NetBSD: softfloat-specialize.h,v 1.3 2020/09/02 03:41:56 thorpej 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 *
21 1.1 ross * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 1.1 ross * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 1.1 ross * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 1.1 ross * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 1.1 ross * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 1.1 ross * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 1.1 ross * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 1.1 ross * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 1.1 ross * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 1.1 ross * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 1.1 ross * POSSIBILITY OF SUCH DAMAGE.
32 1.1 ross */
33 1.1 ross
34 1.3 thorpej /*============================================================================
35 1.1 ross
36 1.3 thorpej This C source fragment is part of the Berkeley SoftFloat IEEE Floating-Point
37 1.3 thorpej Arithmetic Package, Release 2c, by John R. Hauser.
38 1.1 ross
39 1.3 thorpej THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
40 1.3 thorpej been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
41 1.3 thorpej RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
42 1.3 thorpej AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER
43 1.3 thorpej PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR
44 1.3 thorpej THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY
45 1.3 thorpej INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE
46 1.3 thorpej (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER
47 1.3 thorpej PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR
48 1.3 thorpej INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE
49 1.3 thorpej SOFTWARE.
50 1.3 thorpej
51 1.3 thorpej Derivative works require also that (1) the source code for the derivative work
52 1.3 thorpej includes prominent notice that the work is derivative, and (2) the source code
53 1.3 thorpej includes prominent notice of these three paragraphs for those parts of this
54 1.3 thorpej code that are retained.
55 1.3 thorpej
56 1.3 thorpej =============================================================================*/
57 1.3 thorpej
58 1.3 thorpej /*----------------------------------------------------------------------------
59 1.3 thorpej | Underflow tininess-detection mode, statically initialized to default value.
60 1.3 thorpej | (The declaration in `softfloat.h' must match the `int8' type here.)
61 1.3 thorpej *----------------------------------------------------------------------------*/
62 1.1 ross /* [ MP safe, does not change dynamically ] */
63 1.1 ross int float_detect_tininess = float_tininess_after_rounding;
64 1.1 ross
65 1.3 thorpej /*----------------------------------------------------------------------------
66 1.3 thorpej | Internal canonical NaN format.
67 1.3 thorpej *----------------------------------------------------------------------------*/
68 1.1 ross typedef struct {
69 1.1 ross flag sign;
70 1.1 ross bits64 high, low;
71 1.1 ross } commonNaNT;
72 1.1 ross
73 1.3 thorpej /*----------------------------------------------------------------------------
74 1.3 thorpej | The pattern for a default generated single-precision NaN.
75 1.3 thorpej *----------------------------------------------------------------------------*/
76 1.1 ross #define float32_default_nan 0xFFC00000
77 1.1 ross
78 1.3 thorpej /*----------------------------------------------------------------------------
79 1.3 thorpej | Returns 1 if the single-precision floating-point value `a' is a NaN;
80 1.3 thorpej | otherwise returns 0.
81 1.3 thorpej *----------------------------------------------------------------------------*/
82 1.3 thorpej
83 1.1 ross static flag float32_is_nan( float32 a )
84 1.1 ross {
85 1.1 ross
86 1.1 ross return ( 0xFF000000 < (bits32) ( a<<1 ) );
87 1.1 ross
88 1.1 ross }
89 1.1 ross
90 1.3 thorpej /*----------------------------------------------------------------------------
91 1.3 thorpej | Returns 1 if the single-precision floating-point value `a' is a signaling
92 1.3 thorpej | NaN; otherwise returns 0.
93 1.3 thorpej *----------------------------------------------------------------------------*/
94 1.3 thorpej
95 1.1 ross flag float32_is_signaling_nan( float32 a )
96 1.1 ross {
97 1.1 ross
98 1.1 ross return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99 1.1 ross
100 1.1 ross }
101 1.1 ross
102 1.3 thorpej /*----------------------------------------------------------------------------
103 1.3 thorpej | Returns the result of converting the single-precision floating-point NaN
104 1.3 thorpej | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
105 1.3 thorpej | exception is raised.
106 1.3 thorpej *----------------------------------------------------------------------------*/
107 1.3 thorpej
108 1.1 ross static commonNaNT float32ToCommonNaN( float32 a )
109 1.1 ross {
110 1.1 ross commonNaNT z;
111 1.1 ross
112 1.1 ross if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
113 1.1 ross z.sign = a>>31;
114 1.1 ross z.low = 0;
115 1.1 ross z.high = ( (bits64) a )<<41;
116 1.1 ross return z;
117 1.1 ross
118 1.1 ross }
119 1.1 ross
120 1.3 thorpej /*----------------------------------------------------------------------------
121 1.3 thorpej | Returns the result of converting the canonical NaN `a' to the single-
122 1.3 thorpej | precision floating-point format.
123 1.3 thorpej *----------------------------------------------------------------------------*/
124 1.3 thorpej
125 1.1 ross static float32 commonNaNToFloat32( commonNaNT a )
126 1.1 ross {
127 1.1 ross
128 1.1 ross return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
129 1.1 ross
130 1.1 ross }
131 1.1 ross
132 1.3 thorpej /*----------------------------------------------------------------------------
133 1.3 thorpej | Takes two single-precision floating-point values `a' and `b', one of which
134 1.3 thorpej | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
135 1.3 thorpej | signaling NaN, the invalid exception is raised.
136 1.3 thorpej *----------------------------------------------------------------------------*/
137 1.3 thorpej
138 1.1 ross static float32 propagateFloat32NaN( float32 a, float32 b )
139 1.1 ross {
140 1.1 ross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
141 1.1 ross
142 1.1 ross aIsNaN = float32_is_nan( a );
143 1.1 ross aIsSignalingNaN = float32_is_signaling_nan( a );
144 1.1 ross bIsNaN = float32_is_nan( b );
145 1.1 ross bIsSignalingNaN = float32_is_signaling_nan( b );
146 1.1 ross a |= 0x00400000;
147 1.1 ross b |= 0x00400000;
148 1.1 ross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
149 1.1 ross if ( aIsSignalingNaN ) {
150 1.1 ross if ( bIsSignalingNaN ) goto returnLargerSignificand;
151 1.1 ross return bIsNaN ? b : a;
152 1.1 ross }
153 1.1 ross else if ( aIsNaN ) {
154 1.1 ross if ( bIsSignalingNaN | ! bIsNaN ) return a;
155 1.1 ross returnLargerSignificand:
156 1.1 ross if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
157 1.1 ross if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
158 1.1 ross return ( a < b ) ? a : b;
159 1.1 ross }
160 1.1 ross else {
161 1.1 ross return b;
162 1.1 ross }
163 1.1 ross
164 1.1 ross }
165 1.1 ross
166 1.3 thorpej /*
167 1.3 thorpej * float64_default_nan, float64_is_nan(), float64_is_signaling_nan()
168 1.3 thorpej * have moved to softfloat.h.
169 1.3 thorpej */
170 1.3 thorpej
171 1.3 thorpej /*----------------------------------------------------------------------------
172 1.3 thorpej | Returns the result of converting the double-precision floating-point NaN
173 1.3 thorpej | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
174 1.3 thorpej | exception is raised.
175 1.3 thorpej *----------------------------------------------------------------------------*/
176 1.1 ross
177 1.1 ross static commonNaNT float64ToCommonNaN( float64 a )
178 1.1 ross {
179 1.1 ross commonNaNT z;
180 1.1 ross
181 1.1 ross if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
182 1.1 ross z.sign = a>>63;
183 1.1 ross z.low = 0;
184 1.1 ross z.high = a<<12;
185 1.1 ross return z;
186 1.1 ross
187 1.1 ross }
188 1.1 ross
189 1.3 thorpej /*----------------------------------------------------------------------------
190 1.3 thorpej | Returns the result of converting the canonical NaN `a' to the double-
191 1.3 thorpej | precision floating-point format.
192 1.3 thorpej *----------------------------------------------------------------------------*/
193 1.3 thorpej
194 1.1 ross static float64 commonNaNToFloat64( commonNaNT a )
195 1.1 ross {
196 1.1 ross
197 1.1 ross return
198 1.1 ross ( ( (bits64) a.sign )<<63 )
199 1.1 ross | LIT64( 0x7FF8000000000000 )
200 1.1 ross | ( a.high>>12 );
201 1.1 ross
202 1.1 ross }
203 1.1 ross
204 1.3 thorpej /*----------------------------------------------------------------------------
205 1.3 thorpej | Takes two double-precision floating-point values `a' and `b', one of which
206 1.3 thorpej | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
207 1.3 thorpej | signaling NaN, the invalid exception is raised.
208 1.3 thorpej *----------------------------------------------------------------------------*/
209 1.3 thorpej
210 1.1 ross static float64 propagateFloat64NaN( float64 a, float64 b )
211 1.1 ross {
212 1.1 ross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
213 1.1 ross
214 1.1 ross aIsNaN = float64_is_nan( a );
215 1.1 ross aIsSignalingNaN = float64_is_signaling_nan( a );
216 1.1 ross bIsNaN = float64_is_nan( b );
217 1.1 ross bIsSignalingNaN = float64_is_signaling_nan( b );
218 1.1 ross a |= LIT64( 0x0008000000000000 );
219 1.1 ross b |= LIT64( 0x0008000000000000 );
220 1.1 ross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
221 1.1 ross if ( aIsSignalingNaN ) {
222 1.1 ross if ( bIsSignalingNaN ) goto returnLargerSignificand;
223 1.1 ross return bIsNaN ? b : a;
224 1.1 ross }
225 1.1 ross else if ( aIsNaN ) {
226 1.1 ross if ( bIsSignalingNaN | ! bIsNaN ) return a;
227 1.1 ross returnLargerSignificand:
228 1.1 ross if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
229 1.1 ross if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
230 1.1 ross return ( a < b ) ? a : b;
231 1.1 ross }
232 1.1 ross else {
233 1.1 ross return b;
234 1.1 ross }
235 1.1 ross
236 1.1 ross }
237 1.1 ross
238 1.1 ross #ifdef FLOATX80
239 1.1 ross
240 1.3 thorpej /*----------------------------------------------------------------------------
241 1.3 thorpej | The pattern for a default generated double-extended-precision NaN.
242 1.3 thorpej | The `high' and `low' values hold the most- and least-significant bits,
243 1.3 thorpej | respectively.
244 1.3 thorpej *----------------------------------------------------------------------------*/
245 1.1 ross #define floatx80_default_nan_high 0xFFFF
246 1.1 ross #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
247 1.1 ross
248 1.3 thorpej /*----------------------------------------------------------------------------
249 1.3 thorpej | Returns 1 if the double-extended-precision floating-point value `a' is a
250 1.3 thorpej | NaN; otherwise returns 0.
251 1.3 thorpej *----------------------------------------------------------------------------*/
252 1.3 thorpej
253 1.1 ross static flag floatx80_is_nan( floatx80 a )
254 1.1 ross {
255 1.1 ross
256 1.1 ross return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
257 1.1 ross
258 1.1 ross }
259 1.1 ross
260 1.3 thorpej /*----------------------------------------------------------------------------
261 1.3 thorpej | Returns 1 if the double-extended-precision floating-point value `a' is a
262 1.3 thorpej | signaling NaN; otherwise returns 0.
263 1.3 thorpej *----------------------------------------------------------------------------*/
264 1.3 thorpej
265 1.1 ross flag floatx80_is_signaling_nan( floatx80 a )
266 1.1 ross {
267 1.1 ross bits64 aLow;
268 1.1 ross
269 1.1 ross aLow = a.low & ~ LIT64( 0x4000000000000000 );
270 1.1 ross return
271 1.1 ross ( ( a.high & 0x7FFF ) == 0x7FFF )
272 1.1 ross && (bits64) ( aLow<<1 )
273 1.1 ross && ( a.low == aLow );
274 1.1 ross
275 1.1 ross }
276 1.1 ross
277 1.3 thorpej /*----------------------------------------------------------------------------
278 1.3 thorpej | Returns the result of converting the double-extended-precision floating-
279 1.3 thorpej | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
280 1.3 thorpej | invalid exception is raised.
281 1.3 thorpej *----------------------------------------------------------------------------*/
282 1.3 thorpej
283 1.1 ross static commonNaNT floatx80ToCommonNaN( floatx80 a )
284 1.1 ross {
285 1.1 ross commonNaNT z;
286 1.1 ross
287 1.1 ross if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
288 1.1 ross z.sign = a.high>>15;
289 1.1 ross z.low = 0;
290 1.1 ross z.high = a.low<<1;
291 1.1 ross return z;
292 1.1 ross
293 1.1 ross }
294 1.1 ross
295 1.3 thorpej /*----------------------------------------------------------------------------
296 1.3 thorpej | Returns the result of converting the canonical NaN `a' to the double-
297 1.3 thorpej | extended-precision floating-point format.
298 1.3 thorpej *----------------------------------------------------------------------------*/
299 1.3 thorpej
300 1.1 ross static floatx80 commonNaNToFloatx80( commonNaNT a )
301 1.1 ross {
302 1.1 ross floatx80 z;
303 1.1 ross
304 1.1 ross z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
305 1.1 ross z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
306 1.1 ross return z;
307 1.1 ross
308 1.1 ross }
309 1.1 ross
310 1.3 thorpej /*----------------------------------------------------------------------------
311 1.3 thorpej | Takes two double-extended-precision floating-point values `a' and `b', one
312 1.3 thorpej | of which is a NaN, and returns the appropriate NaN result. If either `a' or
313 1.3 thorpej | `b' is a signaling NaN, the invalid exception is raised.
314 1.3 thorpej *----------------------------------------------------------------------------*/
315 1.3 thorpej
316 1.1 ross static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
317 1.1 ross {
318 1.1 ross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
319 1.1 ross
320 1.1 ross aIsNaN = floatx80_is_nan( a );
321 1.1 ross aIsSignalingNaN = floatx80_is_signaling_nan( a );
322 1.1 ross bIsNaN = floatx80_is_nan( b );
323 1.1 ross bIsSignalingNaN = floatx80_is_signaling_nan( b );
324 1.1 ross a.low |= LIT64( 0xC000000000000000 );
325 1.1 ross b.low |= LIT64( 0xC000000000000000 );
326 1.1 ross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
327 1.1 ross if ( aIsSignalingNaN ) {
328 1.1 ross if ( bIsSignalingNaN ) goto returnLargerSignificand;
329 1.1 ross return bIsNaN ? b : a;
330 1.1 ross }
331 1.1 ross else if ( aIsNaN ) {
332 1.1 ross if ( bIsSignalingNaN | ! bIsNaN ) return a;
333 1.1 ross returnLargerSignificand:
334 1.1 ross if ( a.low < b.low ) return b;
335 1.1 ross if ( b.low < a.low ) return a;
336 1.1 ross return ( a.high < b.high ) ? a : b;
337 1.1 ross }
338 1.1 ross else {
339 1.1 ross return b;
340 1.1 ross }
341 1.1 ross
342 1.1 ross }
343 1.1 ross
344 1.1 ross #endif
345 1.1 ross
346 1.1 ross #ifdef FLOAT128
347 1.1 ross
348 1.3 thorpej /*----------------------------------------------------------------------------
349 1.3 thorpej | The pattern for a default generated quadruple-precision NaN. The `high' and
350 1.3 thorpej | `low' values hold the most- and least-significant bits, respectively.
351 1.3 thorpej *----------------------------------------------------------------------------*/
352 1.1 ross #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
353 1.1 ross #define float128_default_nan_low LIT64( 0x0000000000000000 )
354 1.1 ross
355 1.3 thorpej /*----------------------------------------------------------------------------
356 1.3 thorpej | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
357 1.3 thorpej | otherwise returns 0.
358 1.3 thorpej *----------------------------------------------------------------------------*/
359 1.3 thorpej
360 1.1 ross flag float128_is_nan( float128 a )
361 1.1 ross {
362 1.1 ross
363 1.1 ross return
364 1.1 ross ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
365 1.1 ross && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
366 1.1 ross
367 1.1 ross }
368 1.1 ross
369 1.3 thorpej /*----------------------------------------------------------------------------
370 1.3 thorpej | Returns 1 if the quadruple-precision floating-point value `a' is a
371 1.3 thorpej | signaling NaN; otherwise returns 0.
372 1.3 thorpej *----------------------------------------------------------------------------*/
373 1.3 thorpej
374 1.1 ross flag float128_is_signaling_nan( float128 a )
375 1.1 ross {
376 1.1 ross
377 1.1 ross return
378 1.1 ross ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
379 1.1 ross && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
380 1.1 ross
381 1.1 ross }
382 1.1 ross
383 1.3 thorpej /*----------------------------------------------------------------------------
384 1.3 thorpej | Returns the result of converting the quadruple-precision floating-point NaN
385 1.3 thorpej | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
386 1.3 thorpej | exception is raised.
387 1.3 thorpej *----------------------------------------------------------------------------*/
388 1.3 thorpej
389 1.1 ross static commonNaNT float128ToCommonNaN( float128 a )
390 1.1 ross {
391 1.1 ross commonNaNT z;
392 1.1 ross
393 1.1 ross if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
394 1.1 ross z.sign = a.high>>63;
395 1.1 ross shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
396 1.1 ross return z;
397 1.1 ross
398 1.1 ross }
399 1.1 ross
400 1.3 thorpej /*----------------------------------------------------------------------------
401 1.3 thorpej | Returns the result of converting the canonical NaN `a' to the quadruple-
402 1.3 thorpej | precision floating-point format.
403 1.3 thorpej *----------------------------------------------------------------------------*/
404 1.3 thorpej
405 1.1 ross static float128 commonNaNToFloat128( commonNaNT a )
406 1.1 ross {
407 1.1 ross float128 z;
408 1.1 ross
409 1.1 ross shift128Right( a.high, a.low, 16, &z.high, &z.low );
410 1.1 ross z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
411 1.1 ross return z;
412 1.1 ross
413 1.1 ross }
414 1.1 ross
415 1.3 thorpej /*----------------------------------------------------------------------------
416 1.3 thorpej | Takes two quadruple-precision floating-point values `a' and `b', one of
417 1.3 thorpej | which is a NaN, and returns the appropriate NaN result. If either `a' or
418 1.3 thorpej | `b' is a signaling NaN, the invalid exception is raised.
419 1.3 thorpej *----------------------------------------------------------------------------*/
420 1.3 thorpej
421 1.1 ross static float128 propagateFloat128NaN( float128 a, float128 b )
422 1.1 ross {
423 1.1 ross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
424 1.1 ross
425 1.1 ross aIsNaN = float128_is_nan( a );
426 1.1 ross aIsSignalingNaN = float128_is_signaling_nan( a );
427 1.1 ross bIsNaN = float128_is_nan( b );
428 1.1 ross bIsSignalingNaN = float128_is_signaling_nan( b );
429 1.1 ross a.high |= LIT64( 0x0000800000000000 );
430 1.1 ross b.high |= LIT64( 0x0000800000000000 );
431 1.1 ross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
432 1.1 ross if ( aIsSignalingNaN ) {
433 1.1 ross if ( bIsSignalingNaN ) goto returnLargerSignificand;
434 1.1 ross return bIsNaN ? b : a;
435 1.1 ross }
436 1.1 ross else if ( aIsNaN ) {
437 1.1 ross if ( bIsSignalingNaN | ! bIsNaN ) return a;
438 1.1 ross returnLargerSignificand:
439 1.1 ross if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
440 1.1 ross if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
441 1.1 ross return ( a.high < b.high ) ? a : b;
442 1.1 ross }
443 1.1 ross else {
444 1.1 ross return b;
445 1.1 ross }
446 1.1 ross
447 1.1 ross }
448 1.1 ross
449 1.1 ross #endif
450 1.1 ross
451