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