Annotation of sys/lib/libkern/softfloat-specialize.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: softfloat-specialize.h,v 1.1 2002/04/28 20:55:14 pvalchev Exp $ */
! 2: /* $NetBSD: softfloat-specialize.h,v 1.1 2001/04/26 03:10:47 ross Exp $ */
! 3:
! 4: /* This is a derivative work. */
! 5:
! 6: /*-
! 7: * Copyright (c) 2001 The NetBSD Foundation, Inc.
! 8: * All rights reserved.
! 9: *
! 10: * This code is derived from software contributed to The NetBSD Foundation
! 11: * by Ross Harvey.
! 12: *
! 13: * Redistribution and use in source and binary forms, with or without
! 14: * modification, are permitted provided that the following conditions
! 15: * are met:
! 16: * 1. Redistributions of source code must retain the above copyright
! 17: * notice, this list of conditions and the following disclaimer.
! 18: * 2. Redistributions in binary form must reproduce the above copyright
! 19: * notice, this list of conditions and the following disclaimer in the
! 20: * documentation and/or other materials provided with the distribution.
! 21: * 3. All advertising materials mentioning features or use of this software
! 22: * must display the following acknowledgement:
! 23: * This product includes software developed by the NetBSD
! 24: * Foundation, Inc. and its contributors.
! 25: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 26: * contributors may be used to endorse or promote products derived
! 27: * from this software without specific prior written permission.
! 28: *
! 29: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 30: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 31: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 32: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 33: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 34: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 35: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 36: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 37: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 38: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 39: * POSSIBILITY OF SUCH DAMAGE.
! 40: */
! 41:
! 42: /*
! 43: ===============================================================================
! 44:
! 45: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
! 46: Arithmetic Package, Release 2a.
! 47:
! 48: Written by John R. Hauser. This work was made possible in part by the
! 49: International Computer Science Institute, located at Suite 600, 1947 Center
! 50: Street, Berkeley, California 94704. Funding was partially provided by the
! 51: National Science Foundation under grant MIP-9311980. The original version
! 52: of this code was written as part of a project to build a fixed-point vector
! 53: processor in collaboration with the University of California at Berkeley,
! 54: overseen by Profs. Nelson Morgan and John Wawrzynek. More information
! 55: is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
! 56: arithmetic/SoftFloat.html'.
! 57:
! 58: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable
! 59: effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT
! 60: WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS
! 61: RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL
! 62: RESPONSIBILITY FOR ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM
! 63: THEIR OWN USE OF THE SOFTWARE, AND WHO ALSO EFFECTIVELY INDEMNIFY
! 64: (possibly via similar legal warning) JOHN HAUSER AND THE INTERNATIONAL
! 65: COMPUTER SCIENCE INSTITUTE AGAINST ALL LOSSES, COSTS, OR OTHER PROBLEMS
! 66: ARISING FROM THE USE OF THE SOFTWARE BY THEIR CUSTOMERS AND CLIENTS.
! 67:
! 68: Derivative works are acceptable, even for commercial purposes, so long as
! 69: (1) they include prominent notice that the work is derivative, and (2) they
! 70: include prominent notice akin to these four paragraphs for those parts of
! 71: this code that are retained.
! 72:
! 73: ===============================================================================
! 74: */
! 75:
! 76: /*
! 77: -------------------------------------------------------------------------------
! 78: Underflow tininess-detection mode, statically initialized to default value.
! 79: -------------------------------------------------------------------------------
! 80: */
! 81:
! 82: #ifndef NO_IEEE
! 83:
! 84: /* [ MP safe, does not change dynamically ] */
! 85: int float_detect_tininess = float_tininess_after_rounding;
! 86:
! 87: /*
! 88: -------------------------------------------------------------------------------
! 89: Internal canonical NaN format.
! 90: -------------------------------------------------------------------------------
! 91: */
! 92: typedef struct {
! 93: flag sign;
! 94: bits64 high, low;
! 95: } commonNaNT;
! 96:
! 97: /*
! 98: -------------------------------------------------------------------------------
! 99: The pattern for a default generated single-precision NaN.
! 100: -------------------------------------------------------------------------------
! 101: */
! 102: #define float32_default_nan 0xFFC00000
! 103:
! 104: /*
! 105: -------------------------------------------------------------------------------
! 106: Returns 1 if the single-precision floating-point value `a' is a NaN;
! 107: otherwise returns 0.
! 108: -------------------------------------------------------------------------------
! 109: */
! 110: static flag float32_is_nan( float32 a )
! 111: {
! 112:
! 113: return ( 0xFF000000 < (bits32) ( a<<1 ) );
! 114:
! 115: }
! 116:
! 117: /*
! 118: -------------------------------------------------------------------------------
! 119: Returns 1 if the single-precision floating-point value `a' is a signaling
! 120: NaN; otherwise returns 0.
! 121: -------------------------------------------------------------------------------
! 122: */
! 123: flag float32_is_signaling_nan( float32 a )
! 124: {
! 125:
! 126: return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
! 127:
! 128: }
! 129:
! 130: /*
! 131: -------------------------------------------------------------------------------
! 132: Returns the result of converting the single-precision floating-point NaN
! 133: `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
! 134: exception is raised.
! 135: -------------------------------------------------------------------------------
! 136: */
! 137: static commonNaNT float32ToCommonNaN( float32 a )
! 138: {
! 139: commonNaNT z;
! 140:
! 141: if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
! 142: z.sign = a>>31;
! 143: z.low = 0;
! 144: z.high = ( (bits64) a )<<41;
! 145: return z;
! 146:
! 147: }
! 148:
! 149: /*
! 150: -------------------------------------------------------------------------------
! 151: Returns the result of converting the canonical NaN `a' to the single-
! 152: precision floating-point format.
! 153: -------------------------------------------------------------------------------
! 154: */
! 155: static float32 commonNaNToFloat32( commonNaNT a )
! 156: {
! 157:
! 158: return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
! 159:
! 160: }
! 161:
! 162: /*
! 163: -------------------------------------------------------------------------------
! 164: Takes two single-precision floating-point values `a' and `b', one of which
! 165: is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
! 166: signaling NaN, the invalid exception is raised.
! 167: -------------------------------------------------------------------------------
! 168: */
! 169: static float32 propagateFloat32NaN( float32 a, float32 b )
! 170: {
! 171: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
! 172:
! 173: aIsNaN = float32_is_nan( a );
! 174: aIsSignalingNaN = float32_is_signaling_nan( a );
! 175: bIsNaN = float32_is_nan( b );
! 176: bIsSignalingNaN = float32_is_signaling_nan( b );
! 177: a |= 0x00400000;
! 178: b |= 0x00400000;
! 179: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
! 180: if ( aIsSignalingNaN ) {
! 181: if ( bIsSignalingNaN ) goto returnLargerSignificand;
! 182: return bIsNaN ? b : a;
! 183: }
! 184: else if ( aIsNaN ) {
! 185: if ( bIsSignalingNaN | ! bIsNaN ) return a;
! 186: returnLargerSignificand:
! 187: if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
! 188: if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
! 189: return ( a < b ) ? a : b;
! 190: }
! 191: else {
! 192: return b;
! 193: }
! 194:
! 195: }
! 196:
! 197:
! 198: /*
! 199: -------------------------------------------------------------------------------
! 200: Returns the result of converting the double-precision floating-point NaN
! 201: `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
! 202: exception is raised.
! 203: -------------------------------------------------------------------------------
! 204: */
! 205: static commonNaNT float64ToCommonNaN( float64 a )
! 206: {
! 207: commonNaNT z;
! 208:
! 209: if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
! 210: z.sign = a>>63;
! 211: z.low = 0;
! 212: z.high = a<<12;
! 213: return z;
! 214:
! 215: }
! 216:
! 217: /*
! 218: -------------------------------------------------------------------------------
! 219: Returns the result of converting the canonical NaN `a' to the double-
! 220: precision floating-point format.
! 221: -------------------------------------------------------------------------------
! 222: */
! 223: static float64 commonNaNToFloat64( commonNaNT a )
! 224: {
! 225:
! 226: return
! 227: ( ( (bits64) a.sign )<<63 )
! 228: | LIT64( 0x7FF8000000000000 )
! 229: | ( a.high>>12 );
! 230:
! 231: }
! 232:
! 233: /*
! 234: -------------------------------------------------------------------------------
! 235: Takes two double-precision floating-point values `a' and `b', one of which
! 236: is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
! 237: signaling NaN, the invalid exception is raised.
! 238: -------------------------------------------------------------------------------
! 239: */
! 240: static float64 propagateFloat64NaN( float64 a, float64 b )
! 241: {
! 242: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
! 243:
! 244: aIsNaN = float64_is_nan( a );
! 245: aIsSignalingNaN = float64_is_signaling_nan( a );
! 246: bIsNaN = float64_is_nan( b );
! 247: bIsSignalingNaN = float64_is_signaling_nan( b );
! 248: a |= LIT64( 0x0008000000000000 );
! 249: b |= LIT64( 0x0008000000000000 );
! 250: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
! 251: if ( aIsSignalingNaN ) {
! 252: if ( bIsSignalingNaN ) goto returnLargerSignificand;
! 253: return bIsNaN ? b : a;
! 254: }
! 255: else if ( aIsNaN ) {
! 256: if ( bIsSignalingNaN | ! bIsNaN ) return a;
! 257: returnLargerSignificand:
! 258: if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
! 259: if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
! 260: return ( a < b ) ? a : b;
! 261: }
! 262: else {
! 263: return b;
! 264: }
! 265:
! 266: }
! 267:
! 268: #ifdef FLOATX80
! 269:
! 270: /*
! 271: -------------------------------------------------------------------------------
! 272: The pattern for a default generated extended double-precision NaN. The
! 273: `high' and `low' values hold the most- and least-significant bits,
! 274: respectively.
! 275: -------------------------------------------------------------------------------
! 276: */
! 277: #define floatx80_default_nan_high 0xFFFF
! 278: #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
! 279:
! 280: /*
! 281: -------------------------------------------------------------------------------
! 282: Returns 1 if the extended double-precision floating-point value `a' is a
! 283: NaN; otherwise returns 0.
! 284: -------------------------------------------------------------------------------
! 285: */
! 286: static flag floatx80_is_nan( floatx80 a )
! 287: {
! 288:
! 289: return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
! 290:
! 291: }
! 292:
! 293: /*
! 294: -------------------------------------------------------------------------------
! 295: Returns 1 if the extended double-precision floating-point value `a' is a
! 296: signaling NaN; otherwise returns 0.
! 297: -------------------------------------------------------------------------------
! 298: */
! 299: flag floatx80_is_signaling_nan( floatx80 a )
! 300: {
! 301: bits64 aLow;
! 302:
! 303: aLow = a.low & ~ LIT64( 0x4000000000000000 );
! 304: return
! 305: ( ( a.high & 0x7FFF ) == 0x7FFF )
! 306: && (bits64) ( aLow<<1 )
! 307: && ( a.low == aLow );
! 308:
! 309: }
! 310:
! 311: /*
! 312: -------------------------------------------------------------------------------
! 313: Returns the result of converting the extended double-precision floating-
! 314: point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
! 315: invalid exception is raised.
! 316: -------------------------------------------------------------------------------
! 317: */
! 318: static commonNaNT floatx80ToCommonNaN( floatx80 a )
! 319: {
! 320: commonNaNT z;
! 321:
! 322: if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
! 323: z.sign = a.high>>15;
! 324: z.low = 0;
! 325: z.high = a.low<<1;
! 326: return z;
! 327:
! 328: }
! 329:
! 330: /*
! 331: -------------------------------------------------------------------------------
! 332: Returns the result of converting the canonical NaN `a' to the extended
! 333: double-precision floating-point format.
! 334: -------------------------------------------------------------------------------
! 335: */
! 336: static floatx80 commonNaNToFloatx80( commonNaNT a )
! 337: {
! 338: floatx80 z;
! 339:
! 340: z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
! 341: z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
! 342: return z;
! 343:
! 344: }
! 345:
! 346: /*
! 347: -------------------------------------------------------------------------------
! 348: Takes two extended double-precision floating-point values `a' and `b', one
! 349: of which is a NaN, and returns the appropriate NaN result. If either `a' or
! 350: `b' is a signaling NaN, the invalid exception is raised.
! 351: -------------------------------------------------------------------------------
! 352: */
! 353: static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
! 354: {
! 355: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
! 356:
! 357: aIsNaN = floatx80_is_nan( a );
! 358: aIsSignalingNaN = floatx80_is_signaling_nan( a );
! 359: bIsNaN = floatx80_is_nan( b );
! 360: bIsSignalingNaN = floatx80_is_signaling_nan( b );
! 361: a.low |= LIT64( 0xC000000000000000 );
! 362: b.low |= LIT64( 0xC000000000000000 );
! 363: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
! 364: if ( aIsSignalingNaN ) {
! 365: if ( bIsSignalingNaN ) goto returnLargerSignificand;
! 366: return bIsNaN ? b : a;
! 367: }
! 368: else if ( aIsNaN ) {
! 369: if ( bIsSignalingNaN | ! bIsNaN ) return a;
! 370: returnLargerSignificand:
! 371: if ( a.low < b.low ) return b;
! 372: if ( b.low < a.low ) return a;
! 373: return ( a.high < b.high ) ? a : b;
! 374: }
! 375: else {
! 376: return b;
! 377: }
! 378:
! 379: }
! 380:
! 381: #endif
! 382:
! 383: #ifdef FLOAT128
! 384:
! 385: /*
! 386: -------------------------------------------------------------------------------
! 387: The pattern for a default generated quadruple-precision NaN. The `high' and
! 388: `low' values hold the most- and least-significant bits, respectively.
! 389: -------------------------------------------------------------------------------
! 390: */
! 391: #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
! 392: #define float128_default_nan_low LIT64( 0x0000000000000000 )
! 393:
! 394: /*
! 395: -------------------------------------------------------------------------------
! 396: Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
! 397: otherwise returns 0.
! 398: -------------------------------------------------------------------------------
! 399: */
! 400: flag float128_is_nan( float128 a )
! 401: {
! 402:
! 403: return
! 404: ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
! 405: && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
! 406:
! 407: }
! 408:
! 409: /*
! 410: -------------------------------------------------------------------------------
! 411: Returns 1 if the quadruple-precision floating-point value `a' is a
! 412: signaling NaN; otherwise returns 0.
! 413: -------------------------------------------------------------------------------
! 414: */
! 415: flag float128_is_signaling_nan( float128 a )
! 416: {
! 417:
! 418: return
! 419: ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
! 420: && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
! 421:
! 422: }
! 423:
! 424: /*
! 425: -------------------------------------------------------------------------------
! 426: Returns the result of converting the quadruple-precision floating-point NaN
! 427: `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
! 428: exception is raised.
! 429: -------------------------------------------------------------------------------
! 430: */
! 431: static commonNaNT float128ToCommonNaN( float128 a )
! 432: {
! 433: commonNaNT z;
! 434:
! 435: if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
! 436: z.sign = a.high>>63;
! 437: shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
! 438: return z;
! 439:
! 440: }
! 441:
! 442: /*
! 443: -------------------------------------------------------------------------------
! 444: Returns the result of converting the canonical NaN `a' to the quadruple-
! 445: precision floating-point format.
! 446: -------------------------------------------------------------------------------
! 447: */
! 448: static float128 commonNaNToFloat128( commonNaNT a )
! 449: {
! 450: float128 z;
! 451:
! 452: shift128Right( a.high, a.low, 16, &z.high, &z.low );
! 453: z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
! 454: return z;
! 455:
! 456: }
! 457:
! 458: /*
! 459: -------------------------------------------------------------------------------
! 460: Takes two quadruple-precision floating-point values `a' and `b', one of
! 461: which is a NaN, and returns the appropriate NaN result. If either `a' or
! 462: `b' is a signaling NaN, the invalid exception is raised.
! 463: -------------------------------------------------------------------------------
! 464: */
! 465: static float128 propagateFloat128NaN( float128 a, float128 b )
! 466: {
! 467: flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
! 468:
! 469: aIsNaN = float128_is_nan( a );
! 470: aIsSignalingNaN = float128_is_signaling_nan( a );
! 471: bIsNaN = float128_is_nan( b );
! 472: bIsSignalingNaN = float128_is_signaling_nan( b );
! 473: a.high |= LIT64( 0x0000800000000000 );
! 474: b.high |= LIT64( 0x0000800000000000 );
! 475: if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
! 476: if ( aIsSignalingNaN ) {
! 477: if ( bIsSignalingNaN ) goto returnLargerSignificand;
! 478: return bIsNaN ? b : a;
! 479: }
! 480: else if ( aIsNaN ) {
! 481: if ( bIsSignalingNaN | ! bIsNaN ) return a;
! 482: returnLargerSignificand:
! 483: if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
! 484: if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
! 485: return ( a.high < b.high ) ? a : b;
! 486: }
! 487: else {
! 488: return b;
! 489: }
! 490:
! 491: }
! 492:
! 493: #endif
! 494:
! 495: #endif /* !NO_IEEE */
CVSweb