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