softfloat-specialize revision 206492
1264377Sdes/* $NetBSD: softfloat-specialize,v 1.3 2002/05/12 13:12:45 bjh21 Exp $ */ 2180744Sdes/* $FreeBSD: head/lib/libc/softfloat/softfloat-specialize 206492 2010-04-11 21:22:02Z marius $ */ 3180744Sdes 4180744Sdes/* This is a derivative work. */ 5180744Sdes 6180744Sdes/* 7180744Sdes=============================================================================== 8180744Sdes 9180744SdesThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point 10180744SdesArithmetic Package, Release 2a. 11180744Sdes 12180744SdesWritten by John R. Hauser. This work was made possible in part by the 13180744SdesInternational Computer Science Institute, located at Suite 600, 1947 Center 14180744SdesStreet, Berkeley, California 94704. Funding was partially provided by the 15180744SdesNational Science Foundation under grant MIP-9311980. The original version 16180744Sdesof this code was written as part of a project to build a fixed-point vector 17180744Sdesprocessor in collaboration with the University of California at Berkeley, 18180744Sdesoverseen by Profs. Nelson Morgan and John Wawrzynek. More information 19180744Sdesis available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 20180746Sdesarithmetic/SoftFloat.html'. 21180744Sdes 22262566SdesTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 23262566Sdeshas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 24180744SdesTIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 25180744SdesPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 26180744SdesAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 27180744Sdes 28262566SdesDerivative works are acceptable, even for commercial purposes, so long as 29180750Sdes(1) they include prominent notice that the work is derivative, and (2) they 30262566Sdesinclude prominent notice akin to these four paragraphs for those parts of 31180744Sdesthis code that are retained. 32180744Sdes 33180744Sdes=============================================================================== 34180744Sdes*/ 35180744Sdes 36180744Sdes#include <signal.h> 37180744Sdes 38180744Sdes/* 39180744Sdes------------------------------------------------------------------------------- 40180744SdesUnderflow tininess-detection mode, statically initialized to default value. 41180744Sdes(The declaration in `softfloat.h' must match the `int8' type here.) 42180744Sdes------------------------------------------------------------------------------- 43180744Sdes*/ 44180744Sdes#ifdef SOFTFLOAT_FOR_GCC 45180744Sdesstatic 46180744Sdes#endif 47180744Sdes#ifdef __sparc64__ 48180744Sdesint8 float_detect_tininess = float_tininess_before_rounding; 49180744Sdes#else 50180744Sdesint8 float_detect_tininess = float_tininess_after_rounding; 51180744Sdes#endif 52192595Sdes 53180744Sdes/* 54180744Sdes------------------------------------------------------------------------------- 55180744SdesRaises the exceptions specified by `flags'. Floating-point traps can be 56180744Sdesdefined here if desired. It is currently not possible for such a trap to 57192595Sdessubstitute a result value. If traps are not implemented, this routine 58180744Sdesshould be simply `float_exception_flags |= flags;'. 59180744Sdes------------------------------------------------------------------------------- 60180744Sdes*/ 61180744Sdesfp_except float_exception_mask = 0; 62180744Sdesvoid float_raise( fp_except flags ) 63180744Sdes{ 64180744Sdes 65180744Sdes float_exception_flags |= flags; 66180744Sdes 67180744Sdes if ( flags & float_exception_mask ) { 68180744Sdes raise( SIGFPE ); 69180744Sdes } 70180744Sdes} 71180744Sdes 72180744Sdes/* 73180744Sdes------------------------------------------------------------------------------- 74180744SdesInternal canonical NaN format. 75180744Sdes------------------------------------------------------------------------------- 76180744Sdes*/ 77180744Sdestypedef struct { 78180744Sdes flag sign; 79180744Sdes bits64 high, low; 80180744Sdes} commonNaNT; 81180744Sdes 82180744Sdes/* 83180744Sdes------------------------------------------------------------------------------- 84180744SdesThe pattern for a default generated single-precision NaN. 85180744Sdes------------------------------------------------------------------------------- 86180744Sdes*/ 87180744Sdes#define float32_default_nan 0xFFFFFFFF 88180744Sdes 89180744Sdes/* 90180744Sdes------------------------------------------------------------------------------- 91180744SdesReturns 1 if the single-precision floating-point value `a' is a NaN; 92180744Sdesotherwise returns 0. 93180744Sdes------------------------------------------------------------------------------- 94180744Sdes*/ 95180744Sdes#ifdef SOFTFLOAT_FOR_GCC 96180744Sdesstatic 97180744Sdes#endif 98180744Sdesflag float32_is_nan( float32 a ) 99180744Sdes{ 100180744Sdes 101180744Sdes return ( 0xFF000000 < (bits32) ( a<<1 ) ); 102180744Sdes 103180744Sdes} 104180744Sdes 105180744Sdes/* 106180744Sdes------------------------------------------------------------------------------- 107180744SdesReturns 1 if the single-precision floating-point value `a' is a signaling 108180744SdesNaN; otherwise returns 0. 109180744Sdes------------------------------------------------------------------------------- 110180744Sdes*/ 111180744Sdes#if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) 112264377Sdesstatic 113264377Sdes#endif 114264377Sdesflag float32_is_signaling_nan( float32 a ) 115180744Sdes{ 116180744Sdes 117180744Sdes return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 118180744Sdes 119180744Sdes} 120 121/* 122------------------------------------------------------------------------------- 123Returns 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 125exception is raised. 126------------------------------------------------------------------------------- 127*/ 128static 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------------------------------------------------------------------------------- 142Returns the result of converting the canonical NaN `a' to the single- 143precision floating-point format. 144------------------------------------------------------------------------------- 145*/ 146static float32 commonNaNToFloat32( commonNaNT a ) 147{ 148 149 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); 150 151} 152 153/* 154------------------------------------------------------------------------------- 155Takes two single-precision floating-point values `a' and `b', one of which 156is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 157signaling NaN, the invalid exception is raised. 158------------------------------------------------------------------------------- 159*/ 160static 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 ( aIsNaN ) { 172 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 173 } 174 else { 175 return b; 176 } 177 178} 179 180/* 181------------------------------------------------------------------------------- 182The pattern for a default generated double-precision NaN. 183------------------------------------------------------------------------------- 184*/ 185#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) 186 187/* 188------------------------------------------------------------------------------- 189Returns 1 if the double-precision floating-point value `a' is a NaN; 190otherwise returns 0. 191------------------------------------------------------------------------------- 192*/ 193#ifdef SOFTFLOAT_FOR_GCC 194static 195#endif 196flag float64_is_nan( float64 a ) 197{ 198 199 return ( LIT64( 0xFFE0000000000000 ) < 200 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) ); 201 202} 203 204/* 205------------------------------------------------------------------------------- 206Returns 1 if the double-precision floating-point value `a' is a signaling 207NaN; otherwise returns 0. 208------------------------------------------------------------------------------- 209*/ 210#if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) 211static 212#endif 213flag float64_is_signaling_nan( float64 a ) 214{ 215 216 return 217 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE ) 218 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) ); 219 220} 221 222/* 223------------------------------------------------------------------------------- 224Returns the result of converting the double-precision floating-point NaN 225`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 226exception is raised. 227------------------------------------------------------------------------------- 228*/ 229static commonNaNT float64ToCommonNaN( float64 a ) 230{ 231 commonNaNT z; 232 233 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 234 z.sign = FLOAT64_DEMANGLE(a)>>63; 235 z.low = 0; 236 z.high = FLOAT64_DEMANGLE(a)<<12; 237 return z; 238 239} 240 241/* 242------------------------------------------------------------------------------- 243Returns the result of converting the canonical NaN `a' to the double- 244precision floating-point format. 245------------------------------------------------------------------------------- 246*/ 247static float64 commonNaNToFloat64( commonNaNT a ) 248{ 249 250 return FLOAT64_MANGLE( 251 ( ( (bits64) a.sign )<<63 ) 252 | LIT64( 0x7FF8000000000000 ) 253 | ( a.high>>12 ) ); 254 255} 256 257/* 258------------------------------------------------------------------------------- 259Takes two double-precision floating-point values `a' and `b', one of which 260is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 261signaling NaN, the invalid exception is raised. 262------------------------------------------------------------------------------- 263*/ 264static float64 propagateFloat64NaN( float64 a, float64 b ) 265{ 266 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 267 268 aIsNaN = float64_is_nan( a ); 269 aIsSignalingNaN = float64_is_signaling_nan( a ); 270 bIsNaN = float64_is_nan( b ); 271 bIsSignalingNaN = float64_is_signaling_nan( b ); 272 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 273 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 274 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 275 if ( aIsNaN ) { 276 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 277 } 278 else { 279 return b; 280 } 281 282} 283 284#ifdef FLOATX80 285 286/* 287------------------------------------------------------------------------------- 288The pattern for a default generated extended double-precision NaN. The 289`high' and `low' values hold the most- and least-significant bits, 290respectively. 291------------------------------------------------------------------------------- 292*/ 293#define floatx80_default_nan_high 0xFFFF 294#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 295 296/* 297------------------------------------------------------------------------------- 298Returns 1 if the extended double-precision floating-point value `a' is a 299NaN; otherwise returns 0. 300------------------------------------------------------------------------------- 301*/ 302flag floatx80_is_nan( floatx80 a ) 303{ 304 305 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 306 307} 308 309/* 310------------------------------------------------------------------------------- 311Returns 1 if the extended double-precision floating-point value `a' is a 312signaling NaN; otherwise returns 0. 313------------------------------------------------------------------------------- 314*/ 315flag floatx80_is_signaling_nan( floatx80 a ) 316{ 317 bits64 aLow; 318 319 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 320 return 321 ( ( a.high & 0x7FFF ) == 0x7FFF ) 322 && (bits64) ( aLow<<1 ) 323 && ( a.low == aLow ); 324 325} 326 327/* 328------------------------------------------------------------------------------- 329Returns the result of converting the extended double-precision floating- 330point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 331invalid exception is raised. 332------------------------------------------------------------------------------- 333*/ 334static commonNaNT floatx80ToCommonNaN( floatx80 a ) 335{ 336 commonNaNT z; 337 338 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 339 z.sign = a.high>>15; 340 z.low = 0; 341 z.high = a.low<<1; 342 return z; 343 344} 345 346/* 347------------------------------------------------------------------------------- 348Returns the result of converting the canonical NaN `a' to the extended 349double-precision floating-point format. 350------------------------------------------------------------------------------- 351*/ 352static floatx80 commonNaNToFloatx80( commonNaNT a ) 353{ 354 floatx80 z; 355 356 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 357 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 358 return z; 359 360} 361 362/* 363------------------------------------------------------------------------------- 364Takes two extended double-precision floating-point values `a' and `b', one 365of which is a NaN, and returns the appropriate NaN result. If either `a' or 366`b' is a signaling NaN, the invalid exception is raised. 367------------------------------------------------------------------------------- 368*/ 369static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 370{ 371 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 372 373 aIsNaN = floatx80_is_nan( a ); 374 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 375 bIsNaN = floatx80_is_nan( b ); 376 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 377 a.low |= LIT64( 0xC000000000000000 ); 378 b.low |= LIT64( 0xC000000000000000 ); 379 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 380 if ( aIsNaN ) { 381 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 382 } 383 else { 384 return b; 385 } 386 387} 388 389#endif 390 391#ifdef FLOAT128 392 393/* 394------------------------------------------------------------------------------- 395The pattern for a default generated quadruple-precision NaN. The `high' and 396`low' values hold the most- and least-significant bits, respectively. 397------------------------------------------------------------------------------- 398*/ 399#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) 400#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 401 402/* 403------------------------------------------------------------------------------- 404Returns 1 if the quadruple-precision floating-point value `a' is a NaN; 405otherwise returns 0. 406------------------------------------------------------------------------------- 407*/ 408flag float128_is_nan( float128 a ) 409{ 410 411 return 412 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 413 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 414 415} 416 417/* 418------------------------------------------------------------------------------- 419Returns 1 if the quadruple-precision floating-point value `a' is a 420signaling NaN; otherwise returns 0. 421------------------------------------------------------------------------------- 422*/ 423flag float128_is_signaling_nan( float128 a ) 424{ 425 426 return 427 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 428 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 429 430} 431 432/* 433------------------------------------------------------------------------------- 434Returns the result of converting the quadruple-precision floating-point NaN 435`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 436exception is raised. 437------------------------------------------------------------------------------- 438*/ 439static commonNaNT float128ToCommonNaN( float128 a ) 440{ 441 commonNaNT z; 442 443 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 444 z.sign = a.high>>63; 445 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 446 return z; 447 448} 449 450/* 451------------------------------------------------------------------------------- 452Returns the result of converting the canonical NaN `a' to the quadruple- 453precision floating-point format. 454------------------------------------------------------------------------------- 455*/ 456static float128 commonNaNToFloat128( commonNaNT a ) 457{ 458 float128 z; 459 460 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 461 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 462 return z; 463 464} 465 466/* 467------------------------------------------------------------------------------- 468Takes two quadruple-precision floating-point values `a' and `b', one of 469which is a NaN, and returns the appropriate NaN result. If either `a' or 470`b' is a signaling NaN, the invalid exception is raised. 471------------------------------------------------------------------------------- 472*/ 473static float128 propagateFloat128NaN( float128 a, float128 b ) 474{ 475 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 476 477 aIsNaN = float128_is_nan( a ); 478 aIsSignalingNaN = float128_is_signaling_nan( a ); 479 bIsNaN = float128_is_nan( b ); 480 bIsSignalingNaN = float128_is_signaling_nan( b ); 481 a.high |= LIT64( 0x0000800000000000 ); 482 b.high |= LIT64( 0x0000800000000000 ); 483 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 484 if ( aIsNaN ) { 485 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 486 } 487 else { 488 return b; 489 } 490 491} 492 493#endif 494 495