floatx80 floatx80_round_to_int()

in nwfpe/softfloat.c [2670:2734]


floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
{
    flag aSign;
    int32 aExp;
    bits64 lastBitMask, roundBitsMask;
    int8 roundingMode;
    floatx80 z;

    aExp = extractFloatx80Exp( a );
    if ( 0x403E <= aExp ) {
        if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
            return propagateFloatx80NaN( a, a );
        }
        return a;
    }
    if ( aExp <= 0x3FFE ) {
        if (    ( aExp == 0 )
             && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
            return a;
        }
        roundData->exception |= float_flag_inexact;
        aSign = extractFloatx80Sign( a );
        switch ( roundData->mode ) {
         case float_round_nearest_even:
            if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
               ) {
                return
                    packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
            }
            break;
         case float_round_down:
            return
                  aSign ?
                      packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
                : packFloatx80( 0, 0, 0 );
         case float_round_up:
            return
                  aSign ? packFloatx80( 1, 0, 0 )
                : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
        }
        return packFloatx80( aSign, 0, 0 );
    }
    lastBitMask = 1;
    lastBitMask <<= 0x403E - aExp;
    roundBitsMask = lastBitMask - 1;
    z = a;
    roundingMode = roundData->mode;
    if ( roundingMode == float_round_nearest_even ) {
        z.low += lastBitMask>>1;
        if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
    }
    else if ( roundingMode != float_round_to_zero ) {
        if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
            z.low += roundBitsMask;
        }
    }
    z.low &= ~ roundBitsMask;
    if ( z.low == 0 ) {
        ++z.high;
        z.low = LIT64( 0x8000000000000000 );
    }
    if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
    return z;

}