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