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