Annotation of qemu/fpu/softfloat-specialize.h, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.