Пример #1
0
bool f128M_lt( const float128_t *aPtr, const float128_t *bPtr )
{
    const uint32_t *aWPtr, *bWPtr;
    uint32_t uiA96, uiB96;
    bool signA, signB;
    uint32_t wordA, wordB;

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

}
Пример #2
0
void
 f128M_roundToInt(
     const float128_t *aPtr,
     uint_fast8_t roundingMode,
     bool exact,
     float128_t *zPtr
 )
{
    const uint32_t *aWPtr;
    uint32_t *zWPtr;
    uint32_t ui96;
    int32_t exp;
    uint32_t sigExtra;
    bool sign;
    uint_fast8_t bitPos;
    bool roundNear;
    unsigned int index, lastIndex;
    bool extra;
    uint32_t wordA, bit, wordZ;
    uint_fast8_t carry;
    uint32_t extrasMask;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    zWPtr = (uint32_t *) zPtr;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    ui96 = aWPtr[indexWordHi( 4 )];
    exp = expF128UI96( ui96 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp < 0x3FFF ) {
        zWPtr[indexWord( 4, 2 )] = 0;
        zWPtr[indexWord( 4, 1 )] = 0;
        zWPtr[indexWord( 4, 0 )] = 0;
        sigExtra = aWPtr[indexWord( 4, 2 )];
        if ( ! sigExtra ) {
            sigExtra = aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )];
        }
        if ( ! sigExtra && ! (ui96 & 0x7FFFFFFF) ) goto ui96;
        if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
        sign = signF128UI96( ui96 );
        switch ( roundingMode ) {
         case softfloat_round_near_even:
            if ( ! fracF128UI96( ui96 ) && ! sigExtra ) break;
         case softfloat_round_near_maxMag:
            if ( exp == 0x3FFE ) goto mag1;
            break;
         case softfloat_round_min:
            if ( sign ) goto mag1;
            break;
         case softfloat_round_max:
            if ( ! sign ) goto mag1;
            break;
        }
        ui96 = packToF128UI96( sign, 0, 0 );
        goto ui96;
     mag1:
        ui96 = packToF128UI96( sign, 0x3FFF, 0 );
        goto ui96;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( 0x406F <= exp ) {
        if (
            (exp == 0x7FFF)
                && (fracF128UI96( ui96 )
                        || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
                                | aWPtr[indexWord( 4, 0 )]))
        ) {
            softfloat_propagateNaNF128M( aWPtr, 0, zWPtr );
            return;
        }
        zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
        zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
        zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
        goto ui96;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    bitPos = 0x406F - exp;
    roundNear =
           (roundingMode == softfloat_round_near_maxMag)
        || (roundingMode == softfloat_round_near_even);
    bitPos -= roundNear;
    index = indexWordLo( 4 );
    lastIndex = indexWordHi( 4 );
    extra = 0;
    for (;;) {
        wordA = aWPtr[index];
        if ( bitPos < 32 ) break;
        if ( wordA ) extra = 1;
        zWPtr[index] = 0;
        index += wordIncr;
        bitPos -= 32;
    }
    bit = (uint32_t) 1<<bitPos;
    if ( roundNear ) {
        wordZ = wordA + bit;
        carry = (wordZ < wordA);
        bit <<= 1;
        extrasMask = bit - 1;
        if (
            (roundingMode == softfloat_round_near_even)
                && ! extra && ! (wordZ & extrasMask)
        ) {
            if ( ! bit ) {
                zWPtr[index] = wordZ;
                index += wordIncr;
                wordZ = aWPtr[index] + carry;
                carry &= ! wordZ;
                zWPtr[index] = wordZ & ~1;
                goto propagateCarry;
            }
            wordZ &= ~bit;
        }
    } else {
        extrasMask = bit - 1;
        wordZ = wordA;
        carry = 0;
        if (
               (roundingMode != softfloat_round_minMag)
            && (signF128UI96( ui96 ) ^ (roundingMode == softfloat_round_max))
        ) {
            if ( extra || (wordA & extrasMask) ) {
                wordZ += bit;
                carry = (wordZ < wordA);
            }
        }
    }
    wordZ &= ~extrasMask;
    zWPtr[index] = wordZ;
 propagateCarry:
    while ( index != lastIndex ) {
        index += wordIncr;
        wordZ = aWPtr[index] + carry;
        zWPtr[index] = wordZ;
        carry &= ! wordZ;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exact && (softfloat_compare128M( aWPtr, zWPtr ) != 0) ) {
        softfloat_exceptionFlags |= softfloat_flag_inexact;
    }
    return;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
 ui96:
    zWPtr[indexWordHi( 4 )] = ui96;

}
Пример #3
0
void
 softfloat_roundPackMToF128M(
     bool sign, int32_t exp, uint32_t *extSigPtr, uint32_t *zWPtr )
{
    uint_fast8_t roundingMode;
    bool roundNearEven;
    uint32_t sigExtra;
    bool doIncrement, isTiny;
    static const uint32_t maxSig[4] =
        INIT_UINTM4( 0x0001FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF );
    uint32_t ui, uj;

    roundingMode = softfloat_roundingMode;
    roundNearEven = (roundingMode == softfloat_round_near_even);
    sigExtra = extSigPtr[indexWordLo( 5 )];
    doIncrement = (0x80000000 <= sigExtra);
    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
        doIncrement =
            (roundingMode
                 == (sign ? softfloat_round_min : softfloat_round_max))
                && sigExtra;
    }
    if ( 0x7FFD <= (uint32_t) exp ) {
        if ( exp < 0 ) {
            isTiny =
                   (softfloat_detectTininess
                        == softfloat_tininess_beforeRounding)
                || (exp < -1)
                || ! doIncrement
                || (softfloat_compare128M(
                        extSigPtr + indexMultiwordHi( 5, 4 ), maxSig )
                        < 0);
            softfloat_shiftRightJam160M( extSigPtr, -exp, extSigPtr );
            exp = 0;
            sigExtra = extSigPtr[indexWordLo( 5 )];
            if ( isTiny && sigExtra ) {
                softfloat_raiseFlags( softfloat_flag_underflow );
            }
            doIncrement = (0x80000000 <= sigExtra);
            if (
                   ! roundNearEven
                && (roundingMode != softfloat_round_near_maxMag)
            ) {
                doIncrement =
                    (roundingMode
                         == (sign ? softfloat_round_min : softfloat_round_max))
                        && sigExtra;
            }
        } else if (
               (0x7FFD < exp)
            || ((exp == 0x7FFD) && doIncrement
                    && (softfloat_compare128M(
                            extSigPtr + indexMultiwordHi( 5, 4 ), maxSig )
                            == 0))
        ) {
            softfloat_raiseFlags(
                softfloat_flag_overflow | softfloat_flag_inexact );
            if (
                   roundNearEven
                || (roundingMode == softfloat_round_near_maxMag)
                || (roundingMode
                        == (sign ? softfloat_round_min : softfloat_round_max))
            ) {
                ui = packToF128UI96( sign, 0x7FFF, 0 );
                uj = 0;
            } else {
                ui = packToF128UI96( sign, 0x7FFE, 0x0000FFFF );
                uj = 0xFFFFFFFF;
            }
            zWPtr[indexWordHi( 4 )] = ui;
            zWPtr[indexWord( 4, 2 )] = uj;
            zWPtr[indexWord( 4, 1 )] = uj;
            zWPtr[indexWord( 4, 0 )] = uj;
            return;
        }
    }
    if ( sigExtra ) softfloat_exceptionFlags |= softfloat_flag_inexact;
    uj = extSigPtr[indexWord( 5, 1 )];
    if ( doIncrement ) {
        ++uj;
        if ( uj ) {
            if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) uj &= ~1;
            zWPtr[indexWord( 4, 2 )] = extSigPtr[indexWord( 5, 3 )];
            zWPtr[indexWord( 4, 1 )] = extSigPtr[indexWord( 5, 2 )];
            zWPtr[indexWord( 4, 0 )] = uj;
            ui = extSigPtr[indexWordHi( 5 )];
        } else {
            zWPtr[indexWord( 4, 0 )] = uj;
            ui = extSigPtr[indexWord( 5, 2 )] + 1;
            zWPtr[indexWord( 4, 1 )] = ui;
            uj = extSigPtr[indexWord( 5, 3 )];
            if ( ui ) {
                zWPtr[indexWord( 4, 2 )] = uj;
                ui = extSigPtr[indexWordHi( 5 )];
            } else {
                ++uj;
                zWPtr[indexWord( 4, 2 )] = uj;
                ui = extSigPtr[indexWordHi( 5 )];
                if ( ! uj ) ++ui;
            }
        }
    } else {
        zWPtr[indexWord( 4, 0 )] = uj;
        ui = extSigPtr[indexWord( 5, 2 )];
        zWPtr[indexWord( 4, 1 )] = ui;
        uj |= ui;
        ui = extSigPtr[indexWord( 5, 3 )];
        zWPtr[indexWord( 4, 2 )] = ui;
        uj |= ui;
        ui = extSigPtr[indexWordHi( 5 )];
        uj |= ui;
        if ( ! uj ) exp = 0;
    }
    zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, exp, ui );

}