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