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