[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

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