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