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 #include <signal.h> 36 #include <string.h> 37 #include <unistd.h> 38 39 /* 40 ------------------------------------------------------------------------------- 41 Underflow tininess-detection mode, statically initialized to default value. 42 (The declaration in `softfloat.h' must match the `int8' type here.) 43 ------------------------------------------------------------------------------- 44 */ 45 #ifdef SOFTFLOAT_FOR_GCC 46 static 47 #endif 48 int8 float_detect_tininess = float_tininess_after_rounding; 49 50 /* 51 ------------------------------------------------------------------------------- 52 Raises the exceptions specified by `flags'. Floating-point traps can be 53 defined here if desired. It is currently not possible for such a trap to 54 substitute a result value. If traps are not implemented, this routine 55 should be simply `float_exception_flags |= flags;'. 56 ------------------------------------------------------------------------------- 57 */ 58 #ifdef SOFTFLOAT_FOR_GCC 59 #ifndef set_float_exception_mask 60 #define float_exception_mask _softfloat_float_exception_mask 61 #endif 62 #endif 63 #ifndef set_float_exception_mask 64 fp_except float_exception_mask = 0; 65 #endif 66 void 67 float_raise( fp_except flags ) 68 { 69 70 #if 0 // Don't raise exceptions 71 siginfo_t info; 72 fp_except mask = float_exception_mask; 73 74 #ifdef set_float_exception_mask 75 flags |= set_float_exception_flags(flags, 0); 76 #else 77 float_exception_flags |= flags; 78 flags = float_exception_flags; 79 #endif 80 81 flags &= mask; 82 if ( flags ) { 83 memset(&info, 0, sizeof info); 84 info.si_signo = SIGFPE; 85 info.si_pid = getpid(); 86 info.si_uid = geteuid(); 87 if (flags & float_flag_underflow) 88 info.si_code = FPE_FLTUND; 89 else if (flags & float_flag_overflow) 90 info.si_code = FPE_FLTOVF; 91 else if (flags & float_flag_divbyzero) 92 info.si_code = FPE_FLTDIV; 93 else if (flags & float_flag_invalid) 94 info.si_code = FPE_FLTINV; 95 else if (flags & float_flag_inexact) 96 info.si_code = FPE_FLTRES; 97 sigqueueinfo(getpid(), &info); 98 } 99 #else // Don't raise exceptions 100 float_exception_flags |= flags; 101 #endif // Don't raise exceptions 102 } 103 #undef float_exception_mask 104 105 /* 106 ------------------------------------------------------------------------------- 107 Internal canonical NaN format. 108 ------------------------------------------------------------------------------- 109 */ 110 typedef struct { 111 flag sign; 112 bits64 high, low; 113 } commonNaNT; 114 115 /* 116 ------------------------------------------------------------------------------- 117 The pattern for a default generated single-precision NaN. 118 ------------------------------------------------------------------------------- 119 */ 120 #define float32_default_nan 0xFFFFFFFF 121 122 /* 123 ------------------------------------------------------------------------------- 124 Returns 1 if the single-precision floating-point value `a' is a NaN; 125 otherwise returns 0. 126 ------------------------------------------------------------------------------- 127 */ 128 #ifdef SOFTFLOAT_FOR_GCC 129 static 130 #endif 131 flag float32_is_nan( float32 a ) 132 { 133 134 return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) ); 135 136 } 137 138 /* 139 ------------------------------------------------------------------------------- 140 Returns 1 if the single-precision floating-point value `a' is a signaling 141 NaN; otherwise returns 0. 142 ------------------------------------------------------------------------------- 143 */ 144 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \ 145 !defined(SOFTFLOAT_M68K_FOR_GCC) 146 static 147 #endif 148 flag float32_is_signaling_nan( float32 a ) 149 { 150 151 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 152 153 } 154 155 /* 156 ------------------------------------------------------------------------------- 157 Returns the result of converting the single-precision floating-point NaN 158 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 159 exception is raised. 160 ------------------------------------------------------------------------------- 161 */ 162 static commonNaNT float32ToCommonNaN( float32 a ) 163 { 164 commonNaNT z; 165 166 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 167 z.sign = a>>31; 168 z.low = 0; 169 z.high = ( (bits64) a )<<41; 170 return z; 171 172 } 173 174 /* 175 ------------------------------------------------------------------------------- 176 Returns the result of converting the canonical NaN `a' to the single- 177 precision floating-point format. 178 ------------------------------------------------------------------------------- 179 */ 180 static float32 commonNaNToFloat32( commonNaNT a ) 181 { 182 183 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 ); 184 185 } 186 187 /* 188 ------------------------------------------------------------------------------- 189 Takes two single-precision floating-point values `a' and `b', one of which 190 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 191 signaling NaN, the invalid exception is raised. 192 ------------------------------------------------------------------------------- 193 */ 194 static float32 propagateFloat32NaN( float32 a, float32 b ) 195 { 196 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 197 198 aIsNaN = float32_is_nan( a ); 199 aIsSignalingNaN = float32_is_signaling_nan( a ); 200 bIsNaN = float32_is_nan( b ); 201 bIsSignalingNaN = float32_is_signaling_nan( b ); 202 a |= 0x00400000; 203 b |= 0x00400000; 204 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 205 if ( aIsNaN ) { 206 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 207 } 208 else { 209 return b; 210 } 211 212 } 213 214 /* 215 ------------------------------------------------------------------------------- 216 The pattern for a default generated double-precision NaN. 217 ------------------------------------------------------------------------------- 218 */ 219 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) 220 221 /* 222 ------------------------------------------------------------------------------- 223 Returns 1 if the double-precision floating-point value `a' is a NaN; 224 otherwise returns 0. 225 ------------------------------------------------------------------------------- 226 */ 227 #ifdef SOFTFLOAT_FOR_GCC 228 static 229 #endif 230 flag float64_is_nan( float64 a ) 231 { 232 233 return ( (bits64)LIT64( 0xFFE0000000000000 ) < 234 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) ); 235 236 } 237 238 /* 239 ------------------------------------------------------------------------------- 240 Returns 1 if the double-precision floating-point value `a' is a signaling 241 NaN; otherwise returns 0. 242 ------------------------------------------------------------------------------- 243 */ 244 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \ 245 !defined(SOFTFLOATM68K_FOR_GCC) 246 static 247 #endif 248 flag float64_is_signaling_nan( float64 a ) 249 { 250 251 return 252 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE ) 253 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) ); 254 255 } 256 257 /* 258 ------------------------------------------------------------------------------- 259 Returns the result of converting the double-precision floating-point NaN 260 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 261 exception is raised. 262 ------------------------------------------------------------------------------- 263 */ 264 static commonNaNT float64ToCommonNaN( float64 a ) 265 { 266 commonNaNT z; 267 268 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 269 z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63); 270 z.low = 0; 271 z.high = FLOAT64_DEMANGLE(a)<<12; 272 return z; 273 274 } 275 276 /* 277 ------------------------------------------------------------------------------- 278 Returns the result of converting the canonical NaN `a' to the double- 279 precision floating-point format. 280 ------------------------------------------------------------------------------- 281 */ 282 static float64 commonNaNToFloat64( commonNaNT a ) 283 { 284 285 return FLOAT64_MANGLE( 286 ( ( (bits64) a.sign )<<63 ) 287 | LIT64( 0x7FF8000000000000 ) 288 | ( a.high>>12 ) ); 289 290 } 291 292 /* 293 ------------------------------------------------------------------------------- 294 Takes two double-precision floating-point values `a' and `b', one of which 295 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 296 signaling NaN, the invalid exception is raised. 297 ------------------------------------------------------------------------------- 298 */ 299 static float64 propagateFloat64NaN( float64 a, float64 b ) 300 { 301 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 302 303 aIsNaN = float64_is_nan( a ); 304 aIsSignalingNaN = float64_is_signaling_nan( a ); 305 bIsNaN = float64_is_nan( b ); 306 bIsSignalingNaN = float64_is_signaling_nan( b ); 307 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 308 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 309 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 310 if ( aIsNaN ) { 311 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 312 } 313 else { 314 return b; 315 } 316 317 } 318 319 #ifdef FLOATX80 320 321 /* 322 ------------------------------------------------------------------------------- 323 The pattern for a default generated extended double-precision NaN. The 324 `high' and `low' values hold the most- and least-significant bits, 325 respectively. 326 ------------------------------------------------------------------------------- 327 */ 328 #define floatx80_default_nan_high 0xFFFF 329 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 330 331 /* 332 ------------------------------------------------------------------------------- 333 Returns 1 if the extended double-precision floating-point value `a' is a 334 NaN; otherwise returns 0. 335 ------------------------------------------------------------------------------- 336 */ 337 flag floatx80_is_nan( floatx80 a ) 338 { 339 340 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 341 342 } 343 344 /* 345 ------------------------------------------------------------------------------- 346 Returns 1 if the extended double-precision floating-point value `a' is a 347 signaling NaN; otherwise returns 0. 348 ------------------------------------------------------------------------------- 349 */ 350 flag floatx80_is_signaling_nan( floatx80 a ) 351 { 352 bits64 aLow; 353 354 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 355 return 356 ( ( a.high & 0x7FFF ) == 0x7FFF ) 357 && (bits64) ( aLow<<1 ) 358 && ( a.low == aLow ); 359 360 } 361 362 /* 363 ------------------------------------------------------------------------------- 364 Returns the result of converting the extended double-precision floating- 365 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 366 invalid exception is raised. 367 ------------------------------------------------------------------------------- 368 */ 369 static commonNaNT floatx80ToCommonNaN( floatx80 a ) 370 { 371 commonNaNT z; 372 373 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 374 z.sign = a.high>>15; 375 z.low = 0; 376 z.high = a.low<<1; 377 return z; 378 379 } 380 381 /* 382 ------------------------------------------------------------------------------- 383 Returns the result of converting the canonical NaN `a' to the extended 384 double-precision floating-point format. 385 ------------------------------------------------------------------------------- 386 */ 387 static floatx80 commonNaNToFloatx80( commonNaNT a ) 388 { 389 floatx80 z; 390 391 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 392 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 393 return z; 394 395 } 396 397 /* 398 ------------------------------------------------------------------------------- 399 Takes two extended double-precision floating-point values `a' and `b', one 400 of which is a NaN, and returns the appropriate NaN result. If either `a' or 401 `b' is a signaling NaN, the invalid exception is raised. 402 ------------------------------------------------------------------------------- 403 */ 404 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 405 { 406 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 407 408 aIsNaN = floatx80_is_nan( a ); 409 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 410 bIsNaN = floatx80_is_nan( b ); 411 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 412 a.low |= LIT64( 0xC000000000000000 ); 413 b.low |= LIT64( 0xC000000000000000 ); 414 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 415 if ( aIsNaN ) { 416 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 417 } 418 else { 419 return b; 420 } 421 422 } 423 424 #endif 425 426 #ifdef FLOAT128 427 428 /* 429 ------------------------------------------------------------------------------- 430 The pattern for a default generated quadruple-precision NaN. The `high' and 431 `low' values hold the most- and least-significant bits, respectively. 432 ------------------------------------------------------------------------------- 433 */ 434 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) 435 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 436 437 /* 438 ------------------------------------------------------------------------------- 439 Returns 1 if the quadruple-precision floating-point value `a' is a NaN; 440 otherwise returns 0. 441 ------------------------------------------------------------------------------- 442 */ 443 flag float128_is_nan( float128 a ) 444 { 445 446 return 447 ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 448 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 449 450 } 451 452 /* 453 ------------------------------------------------------------------------------- 454 Returns 1 if the quadruple-precision floating-point value `a' is a 455 signaling NaN; otherwise returns 0. 456 ------------------------------------------------------------------------------- 457 */ 458 flag float128_is_signaling_nan( float128 a ) 459 { 460 461 return 462 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 463 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 464 465 } 466 467 /* 468 ------------------------------------------------------------------------------- 469 Returns the result of converting the quadruple-precision floating-point NaN 470 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 471 exception is raised. 472 ------------------------------------------------------------------------------- 473 */ 474 static commonNaNT float128ToCommonNaN( float128 a ) 475 { 476 commonNaNT z; 477 478 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 479 z.sign = (flag)(a.high>>63); 480 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 481 return z; 482 483 } 484 485 /* 486 ------------------------------------------------------------------------------- 487 Returns the result of converting the canonical NaN `a' to the quadruple- 488 precision floating-point format. 489 ------------------------------------------------------------------------------- 490 */ 491 static float128 commonNaNToFloat128( commonNaNT a ) 492 { 493 float128 z; 494 495 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 496 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 497 return z; 498 499 } 500 501 /* 502 ------------------------------------------------------------------------------- 503 Takes two quadruple-precision floating-point values `a' and `b', one of 504 which is a NaN, and returns the appropriate NaN result. If either `a' or 505 `b' is a signaling NaN, the invalid exception is raised. 506 ------------------------------------------------------------------------------- 507 */ 508 static float128 propagateFloat128NaN( float128 a, float128 b ) 509 { 510 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 511 512 aIsNaN = float128_is_nan( a ); 513 aIsSignalingNaN = float128_is_signaling_nan( a ); 514 bIsNaN = float128_is_nan( b ); 515 bIsSignalingNaN = float128_is_signaling_nan( b ); 516 a.high |= LIT64( 0x0000800000000000 ); 517 b.high |= LIT64( 0x0000800000000000 ); 518 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 519 if ( aIsNaN ) { 520 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 521 } 522 else { 523 return b; 524 } 525 526 } 527 528 #endif 529 530