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