/*----------------------------------------------------------------------------
| Assuming at least one of the two 128-bit floating-point values pointed to by
| `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location
| pointed to by `zWPtr'.  If either original floating-point value is a
| signaling NaN, the invalid exception is raised.  Each of `aWPtr', `bWPtr',
| and `zWPtr' points to an array of four 32-bit elements that concatenate in
| the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
 softfloat_propagateNaNF128M(
     const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr )
{
    bool isSigNaNA;
    const uint32_t *ptr;
    bool isSigNaNB;
    uint32_t uiA96, uiB96, wordMagA, wordMagB;

    isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr );
    ptr = aWPtr;
    if ( ! bWPtr ) {
        if ( isSigNaNA ) softfloat_raiseFlags( softfloat_flag_invalid );
        goto copy;
    }
    isSigNaNB = f128M_isSignalingNaN( (const float128_t *) bWPtr );
    if ( isSigNaNA | isSigNaNB ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        if ( isSigNaNA ) {
            if ( isSigNaNB ) goto returnLargerUIMag;
            if ( softfloat_isNaNF128M( bWPtr ) ) goto copyB;
            goto copy;
        } else {
            if ( softfloat_isNaNF128M( aWPtr ) ) goto copy;
            goto copyB;
        }
    }
 returnLargerUIMag:
    uiA96 = aWPtr[indexWordHi( 4 )];
    uiB96 = bWPtr[indexWordHi( 4 )];
    wordMagA = uiA96 & 0x7FFFFFFF;
    wordMagB = uiB96 & 0x7FFFFFFF;
    if ( wordMagA < wordMagB ) goto copyB;
    if ( wordMagB < wordMagA ) goto copy;
    wordMagA = aWPtr[indexWord( 4, 2 )];
    wordMagB = bWPtr[indexWord( 4, 2 )];
    if ( wordMagA < wordMagB ) goto copyB;
    if ( wordMagB < wordMagA ) goto copy;
    wordMagA = aWPtr[indexWord( 4, 1 )];
    wordMagB = bWPtr[indexWord( 4, 1 )];
    if ( wordMagA < wordMagB ) goto copyB;
    if ( wordMagB < wordMagA ) goto copy;
    wordMagA = aWPtr[indexWord( 4, 0 )];
    wordMagB = bWPtr[indexWord( 4, 0 )];
    if ( wordMagA < wordMagB ) goto copyB;
    if ( wordMagB < wordMagA ) goto copy;
    if ( uiA96 < uiB96 ) goto copy;
 copyB:
    ptr = bWPtr;
 copy:
    zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000;
    zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )];
    zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )];
    zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )];

}
Beispiel #2
0
int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact )
{
    union ui64_f64 uA;
    uint_fast64_t uiA;
    bool sign;
    int_fast16_t exp;
    uint_fast64_t sig;
    int_fast16_t shiftCount;
#ifdef SOFTFLOAT_FAST_INT64
    struct uint64_extra sigExtra;
#else
    uint32_t extSig[3];
#endif

    uA.f = a;
    uiA = uA.ui;
    sign = signF64UI( uiA );
    exp  = expF64UI( uiA );
    sig  = fracF64UI( uiA );
    if ( exp ) sig |= UINT64_C( 0x0010000000000000 );
    shiftCount = 0x433 - exp;
#ifdef SOFTFLOAT_FAST_INT64
    if ( shiftCount <= 0 ) {
        if ( shiftCount < -11 ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
            return
                ! sign
                    || ((exp == 0x7FF)
                            && (sig != UINT64_C( 0x0010000000000000 )))
                    ? INT64_C( 0x7FFFFFFFFFFFFFFF )
                    : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;
        }
        sigExtra.v = sig<<-shiftCount;
        sigExtra.extra = 0;
    } else {
        sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount );
    }
    return
        softfloat_roundPackToI64(
            sign, sigExtra.v, sigExtra.extra, roundingMode, exact );
#else
    extSig[indexWord( 3, 0 )] = 0;
    if ( shiftCount <= 0 ) {
        if ( shiftCount < -11 ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
            return
                ! sign
                    || ((exp == 0x7FF)
                            && (sig != UINT64_C( 0x0010000000000000 )))
                    ? INT64_C( 0x7FFFFFFFFFFFFFFF )
                    : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;
        }
        sig <<= -shiftCount;
        extSig[indexWord( 3, 2 )] = sig>>32;
        extSig[indexWord( 3, 1 )] = sig;
    } else {
int_fast32_t f128_to_i32_r_minMag( float128_t a, bool exact )
{
    union ui128_f128 uA;
    uint_fast64_t uiA64, uiA0;
    int_fast32_t exp;
    uint_fast64_t sig64;
    int_fast32_t shiftDist;
    bool sign;
    int_fast32_t absZ;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uA.f = a;
    uiA64 = uA.ui.v64;
    uiA0  = uA.ui.v0;
    exp   = expF128UI64( uiA64 );
    sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0);
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    shiftDist = 0x402F - exp;
    if ( 49 <= shiftDist ) {
        if ( exact && (exp | sig64) ) {
            softfloat_raiseFlags( softfloat_flag_inexact );
        }
        return 0;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    sign = signF128UI64( uiA64 );
    if ( shiftDist < 18 ) {
        if (
            sign && (shiftDist == 17)
                && (sig64 < UINT64_C( 0x0000000000020000 ))
        ) {
            if ( exact && sig64 ) {
                softfloat_raiseFlags( softfloat_flag_inexact );
            }
            return -0x7FFFFFFF - 1;
        }
        softfloat_raiseFlags( softfloat_flag_invalid );
        return
            (exp == 0x7FFF) && sig64 ? i32_fromNaN
                : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    sig64 |= UINT64_C( 0x0001000000000000 );
    absZ = sig64>>shiftDist;
    if (
        exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig64)
    ) {
        softfloat_raiseFlags( softfloat_flag_inexact );
    }
    return sign ? -absZ : absZ;

}
Beispiel #4
0
float64_t
 softfloat_roundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig )
{
    uint_fast8_t roundingMode;
    bool roundNearEven;
    uint_fast16_t roundIncrement, roundBits;
    bool isTiny;
    uint_fast64_t uiZ;
    union ui64_f64 uZ;

    roundingMode = softfloat_roundingMode;
    roundNearEven = (roundingMode == softfloat_round_near_even);
    roundIncrement = 0x200;
    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
        roundIncrement =
            (roundingMode
                 == (sign ? softfloat_round_min : softfloat_round_max))
                ? 0x3FF
                : 0;
    }
    roundBits = sig & 0x3FF;
    if ( 0x7FD <= (uint16_t) exp ) {
        if ( exp < 0 ) {
            isTiny =
                   (softfloat_detectTininess
                        == softfloat_tininess_beforeRounding)
                || (exp < -1)
                || (sig + roundIncrement < UINT64_C( 0x8000000000000000 ));
            sig = softfloat_shiftRightJam64( sig, -exp );
            exp = 0;
            roundBits = sig & 0x3FF;
            if ( isTiny && roundBits ) {
                softfloat_raiseFlags( softfloat_flag_underflow );
            }
        } else if (
            (0x7FD < exp)
                || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement)
        ) {
            softfloat_raiseFlags(
                softfloat_flag_overflow | softfloat_flag_inexact );
            uiZ = packToF64UI( sign, 0x7FF, 0 ) - ! roundIncrement;
            goto uiZ;
        }
    }
    if ( roundBits ) softfloat_exceptionFlags |= softfloat_flag_inexact;
    sig = (sig + roundIncrement)>>10;
    sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven);
    uiZ = packToF64UI( sign, sig ? exp : 0, sig );
 uiZ:
    uZ.ui = uiZ;
    return uZ.f;

}
Beispiel #5
0
/*----------------------------------------------------------------------------
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
| point values, at least one of which is a NaN, returns the bit pattern of
| the combined NaN result.  If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
 softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB )
{
    bool isSigNaNA, isSigNaNB;
    uint_fast16_t uiNonsigA, uiNonsigB, uiMagA, uiMagB;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    isSigNaNA = softfloat_isSigNaNF16UI( uiA );
    isSigNaNB = softfloat_isSigNaNF16UI( uiB );
    /*------------------------------------------------------------------------
    | Make NaNs non-signaling.
    *------------------------------------------------------------------------*/
    uiNonsigA = uiA | 0x0200;
    uiNonsigB = uiB | 0x0200;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( isSigNaNA | isSigNaNB ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        if ( isSigNaNA ) {
            if ( isSigNaNB ) goto returnLargerMag;
            return isNaNF16UI( uiB ) ? uiNonsigB : uiNonsigA;
        } else {
            return isNaNF16UI( uiA ) ? uiNonsigA : uiNonsigB;
        }
    }
 returnLargerMag:
    uiMagA = uiA & 0x7FFF;
    uiMagB = uiB & 0x7FFF;
    if ( uiMagA < uiMagB ) return uiNonsigB;
    if ( uiMagB < uiMagA ) return uiNonsigA;
    return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB;

}
Beispiel #6
0
bool f128M_eq_signaling( const float128_t *aPtr, const float128_t *bPtr )
{
    const uint32_t *aWPtr, *bWPtr;
    uint32_t wordA, wordB, uiA96, uiB96;
    bool possibleOppositeZeros;
    uint32_t mashWord;

    aWPtr = (const uint32_t *) aPtr;
    bWPtr = (const uint32_t *) bPtr;
    if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return false;
    }
    wordA = aWPtr[indexWord( 4, 2 )];
    wordB = bWPtr[indexWord( 4, 2 )];
    if ( wordA != wordB ) return false;
    uiA96 = aWPtr[indexWordHi( 4 )];
    uiB96 = bWPtr[indexWordHi( 4 )];
    possibleOppositeZeros = false;
    if ( uiA96 != uiB96 ) {
        possibleOppositeZeros = (((uiA96 | uiB96) & 0x7FFFFFFF) == 0);
        if ( ! possibleOppositeZeros ) return false;
    }
    mashWord = wordA | wordB;
    wordA = aWPtr[indexWord( 4, 1 )];
    wordB = bWPtr[indexWord( 4, 1 )];
    if ( wordA != wordB ) return false;
    mashWord |= wordA | wordB;
    wordA = aWPtr[indexWord( 4, 0 )];
    wordB = bWPtr[indexWord( 4, 0 )];
    return
        (wordA == wordB)
            && (! possibleOppositeZeros || ((mashWord | wordA | wordB) == 0));

}
Beispiel #7
0
/*----------------------------------------------------------------------------
| Assuming at least one of the two 80-bit extended floating-point values
| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result
| at the location pointed to by 'zSPtr'.  If either original floating-point
| value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
 softfloat_propagateNaNExtF80M(
     const struct extFloat80M *aSPtr,
     const struct extFloat80M *bSPtr,
     struct extFloat80M *zSPtr
 )
{
    uint_fast16_t ui64;
    uint_fast64_t ui0;

    ui64 = aSPtr->signExp;
    ui0  = aSPtr->signif;
    if (
        softfloat_isSigNaNExtF80UI( ui64, ui0 )
            || (bSPtr
                    && (ui64 = bSPtr->signExp,
                        ui0  = bSPtr->signif,
                        softfloat_isSigNaNExtF80UI( ui64, ui0 )))
    ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
    }
    zSPtr->signExp = defaultNaNExtF80UI64;
    zSPtr->signif  = defaultNaNExtF80UI0;

}
uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t a, bool exact )
{
    union { struct extFloat80M s; extFloat80_t f; } uA;
    uint_fast16_t uiA64;
    int_fast32_t exp;
    uint_fast64_t sig;
    int_fast32_t shiftCount;
    uint_fast32_t z;

    uA.f = a;
    uiA64 = uA.s.signExp;
    exp = expExtF80UI64( uiA64 );
    sig = uA.s.signif;
    shiftCount = 0x403E - exp;
    if ( 64 <= shiftCount ) {
        if ( exact && (exp | sig) ) {
            softfloat_exceptionFlags |= softfloat_flag_inexact;
        }
        return 0;
    }
    if ( signExtF80UI64( uiA64 ) || (shiftCount < 32) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return 0xFFFFFFFF;
    }
    z = sig>>shiftCount;
    if ( exact && ((uint_fast64_t) z<<shiftCount != sig) ) {
        softfloat_exceptionFlags |= softfloat_flag_inexact;
    }
    return z;

}
Beispiel #9
0
uint_fast64_t
 extF80_to_ui64( extFloat80_t a, uint_fast8_t roundingMode, bool exact )
{
    union { struct extFloat80M s; extFloat80_t f; } uA;
    uint_fast16_t uiA64;
    int_fast32_t exp, shiftCount;
    bool sign;
    uint_fast64_t sig, sigExtra;
    struct uint64_extra sig64Extra;

    uA.f = a;
    uiA64 = uA.s.signExp;
    exp = expExtF80UI64( uiA64 );
    shiftCount = 0x403E - exp;
    if ( shiftCount < 0 ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return UINT64_C( 0xFFFFFFFFFFFFFFFF );
    }
    sign = signExtF80UI64( uiA64 );
    sig = uA.s.signif;
    sigExtra = 0;
    if ( shiftCount ) {
        sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftCount );
        sig = sig64Extra.v;
        sigExtra = sig64Extra.extra;
    }
    return
        softfloat_roundPackToUI64( sign, sig, sigExtra, roundingMode, exact );

}
Beispiel #10
0
bool f128_eq( float128_t a, float128_t b )
{
    union ui128_f128 uA;
    uint_fast64_t uiA64, uiA0;
    union ui128_f128 uB;
    uint_fast64_t uiB64, uiB0;

    uA.f = a;
    uiA64 = uA.ui.v64;
    uiA0  = uA.ui.v0;
    uB.f = b;
    uiB64 = uB.ui.v64;
    uiB0  = uB.ui.v0;
    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
        if (
               softfloat_isSigNaNF128UI( uiA64, uiA0 )
            || softfloat_isSigNaNF128UI( uiB64, uiB0 )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    return
           (uiA0 == uiB0)
        && (   (uiA64 == uiB64)
            || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))
           );

}
Beispiel #11
0
bool f32_eq( float32_t a, float32_t b )
{
    union ui32_f32 uA;
    uint_fast32_t uiA;
    union ui32_f32 uB;
    uint_fast32_t uiB;

    uA.f = a;
    uiA = uA.ui;
    uB.f = b;
    uiB = uB.ui;
    if (
           ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) )
        || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) )
    ) {
        if (
            softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    return ( uiA == uiB ) || ! (uint32_t) ( ( uiA | uiB )<<1 );

}
Beispiel #12
0
bool f32_le( float32_t a, float32_t b )
{
    union ui32_f32 uA;
    uint_fast32_t uiA;
    union ui32_f32 uB;
    uint_fast32_t uiB;
    bool signA, signB;

    uA.f = a;
    uiA = uA.ui;
    uB.f = b;
    uiB = uB.ui;
    if (
           ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) )
        || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) )
    ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return false;
    }
    signA = signF32UI( uiA );
    signB = signF32UI( uiB );
    return
        ( signA != signB ) ? signA || ! (uint32_t) ( ( uiA | uiB )<<1 )
            : ( uiA == uiB ) || ( signA ^ ( uiA < uiB ) );

}
uint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact )
{
    union ui64_f64 uA;
    uint_fast64_t uiA;
    int_fast16_t exp;
    uint_fast64_t sig;
    int_fast16_t shiftCount;
    uint_fast32_t z;

    uA.f = a;
    uiA = uA.ui;
    exp = expF64UI( uiA );
    sig = fracF64UI( uiA );
    if ( exp < 0x3FF ) {
        if ( exact && ( exp | sig ) ) {
            softfloat_exceptionFlags |= softfloat_flag_inexact;
        }
        return 0;
    }
    if ( signF64UI( uiA ) || ( 0x41E < exp ) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return 0xFFFFFFFF;
    }
    sig |= UINT64_C( 0x0010000000000000 );
    shiftCount = 0x433 - exp;
    z = sig>>shiftCount;
    if ( exact && ( (uint_fast64_t) z<<shiftCount != sig ) ) {
        softfloat_exceptionFlags |= softfloat_flag_inexact;
    }
    return z;

}
Beispiel #14
0
uint_fast64_t f64_to_ui64( float64_t a, int_fast8_t roundingMode, bool exact )
{
    union ui64_f64 uA;
    uint_fast64_t uiA;
    bool sign;
    int_fast16_t exp;
    uint_fast64_t sig;
    int_fast16_t shiftCount;
    struct uint64_extra sigExtra;

    uA.f = a;
    uiA = uA.ui;
    sign = signF64UI( uiA );
    exp = expF64UI( uiA );
    sig = fracF64UI( uiA );
    if ( exp ) sig |= UINT64_C( 0x0010000000000000 );
    shiftCount = 0x433 - exp;
    if ( shiftCount <= 0 ) {
        if ( 0x43E < exp ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
            return UINT64_C( 0xFFFFFFFFFFFFFFFF );
        }
        sigExtra.v = sig<<( - shiftCount );
        sigExtra.extra = 0;
    } else {
        sigExtra = softfloat_shift64ExtraRightJam( sig, 0, shiftCount );
    }
    return
        softfloat_roundPackToUI64(
            sign, sigExtra.v, sigExtra.extra, roundingMode, exact );

}
Beispiel #15
0
bool extF80_eq( extFloat80_t a, extFloat80_t b )
{
    union { struct extFloat80M s; extFloat80_t f; } uA;
    uint_fast16_t uiA64;
    uint_fast64_t uiA0;
    union { struct extFloat80M s; extFloat80_t f; } uB;
    uint_fast16_t uiB64;
    uint_fast64_t uiB0;

    uA.f = a;
    uiA64 = uA.s.signExp;
    uiA0  = uA.s.signif;
    uB.f = b;
    uiB64 = uB.s.signExp;
    uiB0  = uB.s.signif;
    if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) {
        if (
               softfloat_isSigNaNExtF80UI( uiA64, uiA0 )
            || softfloat_isSigNaNExtF80UI( uiB64, uiB0 )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    return
           (uiA0 == uiB0)
        && ((uiA64 == uiB64) || (! uiA0 && ! ((uiA64 | uiB64) & 0x7FFF)));

}
Beispiel #16
0
int_fast64_t f32_to_i64( float32_t a, int_fast8_t roundingMode, bool exact )
{
    union ui32_f32 uA;
    uint_fast32_t uiA;
    bool sign;
    int_fast16_t exp;
    uint_fast32_t sig;
    int_fast16_t shiftCount;
    uint_fast64_t sig64, extra;
    struct uint64_extra sig64Extra;

    uA.f = a;
    uiA = uA.ui;
    sign = signF32UI( uiA );
    exp = expF32UI( uiA );
    sig = fracF32UI( uiA );
    shiftCount = 0xBE - exp;
    if ( shiftCount < 0 ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        if ( ! sign || ( ( exp == 0xFF ) && sig ) ) {
            return INT64_C( 0x7FFFFFFFFFFFFFFF );
        }
        return - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;
    }
    if ( exp ) sig |= 0x00800000;
    sig64 = (uint_fast64_t) sig<<40;
    extra = 0;
    if ( shiftCount ) {
        sig64Extra = softfloat_shift64ExtraRightJam( sig64, 0, shiftCount );
        sig64 = sig64Extra.v;
        extra = sig64Extra.extra;
    }
    return softfloat_roundPackToI64( sign, sig64, extra, roundingMode, exact );

}
Beispiel #17
0
bool f128_le( float128_t a, float128_t b )
{
    union ui128_f128 uA;
    uint_fast64_t uiA64, uiA0;
    union ui128_f128 uB;
    uint_fast64_t uiB64, uiB0;
    bool signA, signB;

    uA.f = a;
    uiA64 = uA.ui.v64;
    uiA0  = uA.ui.v0;
    uB.f = b;
    uiB64 = uB.ui.v64;
    uiB0  = uB.ui.v0;
    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return false;
    }
    signA = signF128UI64( uiA64 );
    signB = signF128UI64( uiB64 );
    return
        (signA != signB)
            ? signA
                  || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
                            | uiA0 | uiB0)
            : ((uiA64 == uiB64) && (uiA0 == uiB0))
                  || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));

}
Beispiel #18
0
uint_fast64_t
 extF80M_to_ui64(
     const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact )
{
    const struct extFloat80M *aSPtr;
    uint_fast16_t uiA64;
    int32_t exp, shiftCount;
    bool sign;
    uint64_t sig;
    uint32_t extSig[3];

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aSPtr = (const struct extFloat80M *) aPtr;
    uiA64 = aSPtr->signExp;
    exp = expExtF80UI64( uiA64 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    shiftCount = 0x403E - exp;
    if ( shiftCount < 0 ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return UINT64_C( 0xFFFFFFFFFFFFFFFF );
    }
    sign = signExtF80UI64( uiA64 );
    sig = aSPtr->signif;
    extSig[indexWord( 3, 2 )] = sig>>32;
    extSig[indexWord( 3, 1 )] = sig;
    extSig[indexWord( 3, 0 )] = 0;
    if ( shiftCount ) softfloat_shiftRightJam96M( extSig, shiftCount, extSig );
    return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact );

}
Beispiel #19
0
bool f32_le_quiet( float32_t a, float32_t b )
{
    union ui32_f32 uA;
    uint_fast32_t uiA;
    union ui32_f32 uB;
    uint_fast32_t uiB;
    bool signA, signB;

    uA.f = a;
    uiA = uA.ui;
    uB.f = b;
    uiB = uB.ui;
    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {
        if (
            softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    signA = signF32UI( uiA );
    signB = signF32UI( uiB );
    return
        (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1)
            : (uiA == uiB) || (signA ^ (uiA < uiB));

}
uint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact )
{
    union ui32_f32 uA;
    uint_fast32_t uiA;
    int_fast16_t exp;
    uint_fast32_t sig;
    int_fast16_t shiftCount;
    uint_fast64_t sig64, z;

    uA.f = a;
    uiA = uA.ui;
    exp = expF32UI( uiA );
    sig = fracF32UI( uiA );
    shiftCount = 0xBE - exp;
    if ( 64 <= shiftCount ) {
        if ( exact && (exp | sig) ) {
            softfloat_exceptionFlags |= softfloat_flag_inexact;
        }
        return 0;
    }
    if ( signF32UI( uiA ) || (shiftCount < 0) ) goto invalid;
    sig |= 0x00800000;
    sig64 = (uint_fast64_t) sig<<40;
    z = sig64>>shiftCount;
    shiftCount = 40 - shiftCount;
    if ( exact && (shiftCount < 0) && (uint32_t) (sig<<(shiftCount & 31)) ) {
        softfloat_exceptionFlags |= softfloat_flag_inexact;
    }
    return z;
 invalid:
    softfloat_raiseFlags( softfloat_flag_invalid );
    return UINT64_C( 0xFFFFFFFFFFFFFFFF );

}
Beispiel #21
0
bool extF80_lt_quiet( extFloat80_t a, extFloat80_t b )
{
    union { struct extFloat80M s; extFloat80_t f; } uA;
    uint_fast16_t uiA64;
    uint_fast64_t uiA0;
    union { struct extFloat80M s; extFloat80_t f; } uB;
    uint_fast16_t uiB64;
    uint_fast64_t uiB0;
    bool signA, signB;

    uA.f = a;
    uiA64 = uA.s.signExp;
    uiA0  = uA.s.signif;
    uB.f = b;
    uiB64 = uB.s.signExp;
    uiB0  = uB.s.signif;
    if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) {
        if (
               softfloat_isSigNaNExtF80UI( uiA64, uiA0 )
            || softfloat_isSigNaNExtF80UI( uiB64, uiB0 )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    signA = signExtF80UI64( uiA64 );
    signB = signExtF80UI64( uiB64 );
    return
        (signA != signB)
            ? signA && (((uiA64 | uiB64) & 0x7FFF) | uiA0 | uiB0)
            : ((uiA64 != uiB64) || (uiA0 != uiB0))
                  && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));

}
/*----------------------------------------------------------------------------
| Interpreting the unsigned integer formed from concatenating `uiA64' and
| `uiA0' as a 128-bit floating-point value, and likewise interpreting the
| unsigned integer formed from concatenating `uiB64' and `uiB0' as another
| 128-bit floating-point value, and assuming at least on of these floating-
| point values is a NaN, returns the bit pattern of the combined NaN result.
| If either original floating-point value is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
 softfloat_propagateNaNF128UI(
     uint_fast64_t uiA64,
     uint_fast64_t uiA0,
     uint_fast64_t uiB64,
     uint_fast64_t uiB0
 )
{
    bool isSigNaNA;
    struct uint128 uiZ;

    isSigNaNA = softfloat_isSigNaNF128UI( uiA64, uiA0 );
    if ( isSigNaNA || softfloat_isSigNaNF128UI( uiB64, uiB0 ) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        if ( isSigNaNA ) goto returnNonsigA;
    }
    if ( isNaNF128UI( uiA64, uiA0 ) ) {
 returnNonsigA:
        uiZ.v64 = uiA64;
        uiZ.v0  = uiA0;
    } else {
        uiZ.v64 = uiB64;
        uiZ.v0  = uiB0;
    }
    uiZ.v64 |= UINT64_C( 0x0000800000000000 );
    return uiZ;

}
Beispiel #23
0
bool f64_lt_quiet( float64_t a, float64_t b )
{
    union ui64_f64 uA;
    uint_fast64_t uiA;
    union ui64_f64 uB;
    uint_fast64_t uiB;
    bool signA, signB;

    uA.f = a;
    uiA = uA.ui;
    uB.f = b;
    uiB = uB.ui;
    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {
        if (
            softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    signA = signF64UI( uiA );
    signB = signF64UI( uiB );
    return
        (signA != signB)
            ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
            : (uiA != uiB) && (signA ^ (uiA < uiB));

}
Beispiel #24
0
void softfloat_invalidExtF80M( struct extFloat80M *zSPtr )
{

    softfloat_raiseFlags( softfloat_flag_invalid );
    zSPtr->signExp = defaultNaNExtF80UI64;
    zSPtr->signif  = defaultNaNExtF80UI0;

}
uint_fast32_t f128_to_ui32_r_minMag( float128_t a, bool exact )
{
    union ui128_f128 uA;
    uint_fast64_t uiA64, uiA0;
    int_fast32_t exp;
    uint_fast64_t sig64;
    int_fast32_t shiftDist;
    bool sign;
    uint_fast32_t z;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uA.f = a;
    uiA64 = uA.ui.v64;
    uiA0  = uA.ui.v0;
    exp   = expF128UI64( uiA64 );
    sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0);
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    shiftDist = 0x402F - exp;
    if ( 49 <= shiftDist ) {
        if ( exact && (exp | sig64) ) {
            softfloat_raiseFlags( softfloat_flag_inexact );
        }
        return 0;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    sign = signF128UI64( uiA64 );
    if ( sign || (shiftDist < 17) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return
            (exp == 0x7FFF) && sig64 ? ui32_fromNaN
                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    sig64 |= UINT64_C( 0x0001000000000000 );
    z = sig64>>shiftDist;
    if ( exact && ((uint_fast64_t) z<<shiftDist != sig64) ) {
        softfloat_raiseFlags( softfloat_flag_inexact );
    }
    return z;

}
uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t a, bool exact )
{
    union { struct extFloat80M s; extFloat80_t f; } uA;
    uint_fast16_t uiA64;
    int_fast32_t exp;
    uint_fast64_t sig;
    int_fast32_t shiftDist;
    bool sign;
    uint_fast32_t z;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uA.f = a;
    uiA64 = uA.s.signExp;
    exp = expExtF80UI64( uiA64 );
    sig = uA.s.signif;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    shiftDist = 0x403E - exp;
    if ( 64 <= shiftDist ) {
        if ( exact && (exp | sig) ) {
            softfloat_raiseFlags( softfloat_flag_inexact );
        }
        return 0;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    sign = signExtF80UI64( uiA64 );
    if ( sign || (shiftDist < 32) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return
            (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
                ? ui32_fromNaN
                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    z = sig>>shiftDist;
    if ( exact && ((uint_fast64_t) z<<shiftDist != sig) ) {
        softfloat_raiseFlags( softfloat_flag_inexact );
    }
    return z;

}
Beispiel #27
0
void softfloat_invalidF128M( uint32_t *zWPtr )
{

    softfloat_raiseFlags( softfloat_flag_invalid );
    zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96;
    zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64;
    zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;
    zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;

}
Beispiel #28
0
/*----------------------------------------------------------------------------
| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating-
| point values, at least one of which is a NaN, returns the bit pattern of
| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
 softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB )
{

    if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
    }
    return defaultNaNF16UI;

}
uint_fast64_t f16_to_ui64_r_minMag( float16_t a, bool exact )
{
    union ui16_f16 uA;
    uint_fast16_t uiA;
    int_fast8_t exp;
    uint_fast16_t frac;
    int_fast8_t shiftDist;
    bool sign;
    uint_fast32_t alignedSig;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uA.f = a;
    uiA = uA.ui;
    exp  = expF16UI( uiA );
    frac = fracF16UI( uiA );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    shiftDist = exp - 0x0F;
    if ( shiftDist < 0 ) {
        if ( exact && (exp | frac) ) {
            softfloat_raiseFlags( softfloat_flag_inexact );
        }
        return 0;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    sign = signF16UI( uiA );
    if ( sign || (exp == 0x1F) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return
            (exp == 0x1F) && frac ? ui64_fromNaN
                : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    alignedSig = (uint_fast32_t) (frac | 0x0400)<<shiftDist;
    if ( exact && (alignedSig & 0x3FF) ) {
        softfloat_raiseFlags( softfloat_flag_inexact );
    }
    return alignedSig>>10;

}
Beispiel #30
0
bool extF80M_lt_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr )
{
    const struct extFloat80M *aSPtr, *bSPtr;
    uint_fast16_t uiA64;
    uint64_t uiA0;
    uint_fast16_t uiB64;
    uint64_t uiB0;
    bool signA, ltMags;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aSPtr = (const struct extFloat80M *) aPtr;
    bSPtr = (const struct extFloat80M *) bPtr;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uiA64 = aSPtr->signExp;
    uiA0  = aSPtr->signif;
    uiB64 = bSPtr->signExp;
    uiB0  = bSPtr->signif;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) {
        if (
               softfloat_isSigNaNExtF80UI( uiA64, uiA0 )
            || softfloat_isSigNaNExtF80UI( uiB64, uiB0 )
        ) {
            softfloat_raiseFlags( softfloat_flag_invalid );
        }
        return false;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    signA = signExtF80UI64( uiA64 );
    if ( (uiA64 ^ uiB64) & 0x8000 ) {
        /*--------------------------------------------------------------------
        | Signs are different.
        *--------------------------------------------------------------------*/
        return signA && ((uiA0 | uiB0) != 0);
    } else {
        /*--------------------------------------------------------------------
        | Signs are the same.
        *--------------------------------------------------------------------*/
        if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) {
            return (softfloat_compareNonnormExtF80M( aSPtr, bSPtr ) < 0);
        }
        if ( uiA64 == uiB64 ) {
            if ( uiA0 == uiB0 ) return false;
            ltMags = (uiA0 < uiB0);
        } else {
            ltMags = (uiA64 < uiB64);
        }
        return signA ^ ltMags;
    }

}