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 488