[BACK]Return to softfloat-specialize.h CVS log [TXT][DIR] Up to [local] / sys / lib / libkern

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