Beispiel #1
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 #2
0
void ui64_to_f128M( uint64_t a, float128_t *zPtr )
{
    uint32_t *zWPtr, uiZ96, uiZ64;
    uint_fast8_t shiftCount;
    uint32_t *ptr;

    zWPtr = (uint32_t *) zPtr;
    uiZ96 = 0;
    uiZ64 = 0;
    zWPtr[indexWord( 4, 1 )] = 0;
    zWPtr[indexWord( 4, 0 )] = 0;
    if ( a ) {
        shiftCount = softfloat_countLeadingZeros64( a ) + 17;
        if ( shiftCount < 32 ) {
            ptr = zWPtr + indexMultiwordHi( 4, 3 );
            ptr[indexWord( 3, 2 )] = 0;
            ptr[indexWord( 3, 1 )] = a>>32;
            ptr[indexWord( 3, 0 )] = a;
            softfloat_shortShiftLeft96M( ptr, shiftCount, ptr );
            ptr[indexWordHi( 3 )] =
                packToF128UI96(
                    0, 0x404E - shiftCount, ptr[indexWordHi( 3 )] );
            return;
        }
        a <<= shiftCount - 32;
        uiZ96 = packToF128UI96( 0, 0x404E - shiftCount, a>>32 );
        uiZ64 = a;
    }
Beispiel #3
0
void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *zPtr )
{
    const struct extFloat80M *aSPtr;
    uint32_t *zWPtr;
    uint_fast16_t uiA64;
    bool sign;
    int32_t exp;
    uint64_t sig;
    struct commonNaN commonNaN;
    uint32_t uiZ96;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aSPtr = (const struct extFloat80M *) aPtr;
    zWPtr = (uint32_t *) zPtr;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uiA64 = aSPtr->signExp;
    sign = signExtF80UI64( uiA64 );
    exp  = expExtF80UI64( uiA64 );
    sig = aSPtr->signif;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    zWPtr[indexWord( 4, 0 )] = 0;
    if ( exp == 0x7FFF ) {
        if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) {
            softfloat_extF80MToCommonNaN( aSPtr, &commonNaN );
            softfloat_commonNaNToF128M( &commonNaN, zWPtr );
            return;
        }
        uiZ96 = packToF128UI96( sign, 0x7FFF, 0 );
        goto uiZ;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp ) --exp;
    if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) {
        if ( ! sig ) {
            uiZ96 = packToF128UI96( sign, 0, 0 );
            goto uiZ;
        }
        exp += softfloat_normExtF80SigM( &sig );
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    zWPtr[indexWord( 4, 1 )] = (uint32_t) sig<<17;
    sig >>= 15;
    zWPtr[indexWord( 4, 2 )] = sig;
    if ( exp < 0 ) {
        zWPtr[indexWordHi( 4 )] = sig>>32;
        softfloat_shiftRight96M(
            &zWPtr[indexMultiwordHi( 4, 3 )],
            -exp,
            &zWPtr[indexMultiwordHi( 4, 3 )]
        );
        exp = 0;
        sig = (uint64_t) zWPtr[indexWordHi( 4 )]<<32;
    }
/*----------------------------------------------------------------------------
| 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 )];

}
void
 softfloat_shortShiftRightExtendM(
     uint_fast8_t size_words,
     const uint32_t *aPtr,
     uint_fast8_t count,
     uint32_t *zPtr
 )
{
    uint_fast8_t negCount;
    unsigned int indexA, lastIndexA;
    uint32_t partWordZ, wordA;

    negCount = -count;
    indexA = indexWordLo( size_words );
    lastIndexA = indexWordHi( size_words );
    zPtr += indexWordLo( size_words + 1 );
    partWordZ = 0;
    for (;;) {
        wordA = aPtr[indexA];
        *zPtr = wordA<<(negCount & 31) | partWordZ;
        zPtr += wordIncr;
        partWordZ = wordA>>count;
        if ( indexA == lastIndexA ) break;
        indexA += wordIncr;
    }
    *zPtr = partWordZ;

}
Beispiel #6
0
void
 softfloat_subM(
     uint_fast8_t size_words,
     const uint32_t *aPtr,
     const uint32_t *bPtr,
     uint32_t *zPtr
 )
{
    unsigned int index, lastIndex;
    uint_fast8_t borrow;
    uint32_t wordA, wordB;

    index = indexWordLo( size_words );
    lastIndex = indexWordHi( size_words );
    borrow = 0;
    for (;;) {
        wordA = aPtr[index];
        wordB = bPtr[index];
        zPtr[index] = wordA - wordB - borrow;
        if ( index == lastIndex ) break;
        borrow = borrow ? (wordA <= wordB) : (wordA < wordB);
        index += wordIncr;
    }

}
Beispiel #7
0
uint_fast8_t
 softfloat_addCarryM(
     uint_fast8_t size_words,
     const uint32_t *aPtr,
     const uint32_t *bPtr,
     uint_fast8_t carry,
     uint32_t *zPtr
 )
{
    unsigned int index, lastIndex;
    uint32_t wordA, wordZ;

    index = indexWordLo( size_words );
    lastIndex = indexWordHi( size_words );
    for (;;) {
        wordA = aPtr[index];
        wordZ = wordA + bPtr[index] + carry;
        zPtr[index] = wordZ;
        carry = carry ? (wordZ <= wordA) : (wordZ < wordA);
        if ( index == lastIndex ) break;
        index += wordIncr;
    }
    return carry;

}
void
 softfloat_shortShiftRightJamM(
     uint_fast8_t size_words,
     const uint32_t *aPtr,
     uint_fast8_t count,
     uint32_t *zPtr
 )
{
    uint_fast8_t negCount;
    unsigned int index, lastIndex;
    uint32_t partWordZ, wordA;

    negCount = -count;
    index = indexWordLo( size_words );
    lastIndex = indexWordHi( size_words );
    wordA = aPtr[index];
    partWordZ = wordA>>count;
    if ( partWordZ<<count != wordA ) partWordZ |= 1;
    while ( index != lastIndex ) {
        wordA = aPtr[index + wordIncr];
        zPtr[index] = wordA<<(negCount & 31) | partWordZ;
        index += wordIncr;
        partWordZ = wordA>>count;
    }
    zPtr[index] = partWordZ;

}
Beispiel #9
0
void
 softfloat_shiftLeftM(
     uint_fast8_t size_words,
     const uint32_t *aPtr,
     uint32_t dist,
     uint32_t *zPtr
 )
{
    uint32_t wordDist;
    uint_fast8_t innerDist;
    uint32_t *destPtr;
    uint_fast8_t i;

    wordDist = dist>>5;
    if ( wordDist < size_words ) {
        aPtr += indexMultiwordLoBut( size_words, wordDist );
        innerDist = dist & 31;
        if ( innerDist ) {
            softfloat_shortShiftLeftM(
                size_words - wordDist,
                aPtr,
                innerDist,
                zPtr + indexMultiwordHiBut( size_words, wordDist )
            );
            if ( ! wordDist ) return;
        } else {
            aPtr += indexWordHi( size_words - wordDist );
            destPtr = zPtr + indexWordHi( size_words );
            for ( i = size_words - wordDist; i; --i ) {
                *destPtr = *aPtr;
                aPtr -= wordIncr;
                destPtr -= wordIncr;
            }
        }
        zPtr += indexMultiwordLo( size_words, wordDist );
    } else {
        wordDist = size_words;
    }
    do {
        *zPtr++ = 0;
        --wordDist;
    } while ( wordDist );

}
Beispiel #10
0
float16_t f128M_to_f16( const float128_t *aPtr )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;
    bool sign;
    int32_t exp;
    uint32_t frac32;
    struct commonNaN commonNaN;
    uint16_t uiZ, frac16;
    union ui16_f16 uZ;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uiA96 = aWPtr[indexWordHi( 4 )];
    sign = signF128UI96( uiA96 );
    exp  = expF128UI96( uiA96 );
    frac32 =
        fracF128UI96( uiA96 )
            | ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
                    | aWPtr[indexWord( 4, 0 )])
                   != 0);
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp == 0x7FFF ) {
        if ( frac32 ) {
            softfloat_f128MToCommonNaN( aWPtr, &commonNaN );
            uiZ = softfloat_commonNaNToF16UI( &commonNaN );
        } else {
            uiZ = packToF16UI( sign, 0x1F, 0 );
        }
        goto uiZ;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    frac16 = frac32>>2 | (frac32 & 3);
    if ( ! (exp | frac16) ) {
        uiZ = packToF16UI( sign, 0, 0 );
        goto uiZ;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    exp -= 0x3FF1;
    if ( sizeof (int_fast16_t) < sizeof (int32_t) ) {
        if ( exp < -0x40 ) exp = -0x40;
    }
    return softfloat_roundPackToF16( sign, exp, frac16 | 0x4000 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
 uiZ:
    uZ.ui = uiZ;
    return uZ.f;

}
Beispiel #11
0
bool f128M_eq( 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;
    wordA = aWPtr[indexWord( 4, 2 )];
    wordB = bWPtr[indexWord( 4, 2 )];
    if ( wordA != wordB ) goto false_checkSigNaNs;
    uiA96 = aWPtr[indexWordHi( 4 )];
    uiB96 = bWPtr[indexWordHi( 4 )];
    possibleOppositeZeros = false;
    if ( uiA96 != uiB96 ) {
        possibleOppositeZeros = (((uiA96 | uiB96) & 0x7FFFFFFF) == 0);
        if ( ! possibleOppositeZeros ) goto false_checkSigNaNs;
    }
    mashWord = wordA | wordB;
    wordA = aWPtr[indexWord( 4, 1 )];
    wordB = bWPtr[indexWord( 4, 1 )];
    if ( wordA != wordB ) goto false_checkSigNaNs;
    mashWord |= wordA | wordB;
    wordA = aWPtr[indexWord( 4, 0 )];
    wordB = bWPtr[indexWord( 4, 0 )];
    if ( wordA != wordB ) goto false_checkSigNaNs;
    if ( possibleOppositeZeros && ((mashWord | wordA | wordB) != 0) ) {
        goto false_checkSigNaNs;
    }
    if ( ! softfloat_isNaNF128M( aWPtr ) && ! softfloat_isNaNF128M( bWPtr ) ) {
        return true;
    }
 false_checkSigNaNs:
    if (
           f128M_isSignalingNaN( (const float128_t *) aWPtr )
        || f128M_isSignalingNaN( (const float128_t *) bWPtr )
    ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
    }
    return false;

}
/*----------------------------------------------------------------------------
| Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN,
| converts this NaN to the common NaN form, and stores the resulting common
| NaN at the location pointed to by `zPtr'.  If the NaN is a signaling NaN,
| the invalid exception is raised.  Argument `aWPtr' 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_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr )
{

    if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
    }
    zPtr->sign = aWPtr[indexWordHi( 4 )]>>31;
    softfloat_shortShiftLeft128M( aWPtr, 16, (uint32_t *) &zPtr->v0 );

}
Beispiel #13
0
float32_t f128M_to_f32( const float128_t *aPtr )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;
    bool sign;
    int32_t exp;
    uint64_t frac64;
    struct commonNaN commonNaN;
    uint32_t uiZ, frac32;
    union ui32_f32 uZ;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    uiA96 = aWPtr[indexWordHi( 4 )];
    sign = signF128UI96( uiA96 );
    exp  = expF128UI96( uiA96 );
    frac64 =
        (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]
            | ((aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )]) != 0);
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp == 0x7FFF ) {
        if ( frac64 ) {
            softfloat_f128MToCommonNaN( aWPtr, &commonNaN );
            uiZ = softfloat_commonNaNToF32UI( &commonNaN );
        } else {
            uiZ = packToF32UI( sign, 0xFF, 0 );
        }
        goto uiZ;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    frac32 = softfloat_shortShiftRightJam64( frac64, 18 );
    if ( ! (exp | frac32) ) {
        uiZ = packToF32UI( sign, 0, 0 );
        goto uiZ;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    exp -= 0x3F81;
    if ( sizeof (int_fast16_t) < sizeof (int32_t) ) {
        if ( exp < -0x1000 ) exp = -0x1000;
    }
    return softfloat_roundPackToF32( sign, exp, frac32 | 0x40000000 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
 uiZ:
    uZ.ui = uiZ;
    return uZ.f;

}
Beispiel #14
0
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
bool softfloat_isNaNF128M( const uint32_t *aWPtr )
{
    uint32_t uiA96;

    uiA96 = aWPtr[indexWordHi( 4 )];
    if ( (uiA96 & 0x7FFF0000) != 0x7FFF0000 ) return false;
    return
        ((uiA96 & 0x0000FFFF) != 0)
            || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
                     | aWPtr[indexWord( 4, 0 )])
                    != 0);

}
Beispiel #15
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);

}
Beispiel #16
0
/*----------------------------------------------------------------------------
| 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;

    ptr = aWPtr;
    isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr );
    if (
        isSigNaNA
            || (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr ))
    ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        if ( isSigNaNA ) goto copy;
    }
    if ( ! softfloat_isNaNF128M( aWPtr ) ) 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 #17
0
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
bool f128M_isSignalingNaN( const float128_t *aPtr )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;

    aWPtr = (const uint32_t *) aPtr;
    uiA96 = aWPtr[indexWordHi( 4 )];
    if ( (uiA96 & 0x7FFF8000) != 0x7FFF0000 ) return false;
    return
        ((uiA96 & 0x00007FFF) != 0)
            || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
                     | aWPtr[indexWord( 4, 0 )])
                    != 0);

}
Beispiel #18
0
void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr )
{
    unsigned int index, lastIndex;
    uint32_t wordA;

    index = indexWordLo( size_words );
    lastIndex = indexWordHi( size_words );
    for (;;) {
        wordA = zPtr[index];
        zPtr[index] = wordA - 1;
        if ( wordA || (index == lastIndex) ) break;
        index += wordIncr;
    }

}
Beispiel #19
0
int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr )
{
    unsigned int index, lastIndex;
    uint32_t wordA, wordB;

    index = indexWordHi( 3 );
    lastIndex = indexWordLo( 3 );
    for (;;) {
        wordA = aPtr[index];
        wordB = bPtr[index];
        if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1;
        if ( index == lastIndex ) break;
        index -= wordIncr;
    }
    return 0;

}
Beispiel #20
0
void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr )
{
    unsigned int index, lastIndex;
    uint_fast8_t carry;
    uint32_t word;

    index = indexWordLo( size_words );
    lastIndex = indexWordHi( size_words );
    carry = 1;
    for (;;) {
        word = ~zPtr[index] + carry;
        zPtr[index] = word;
        if ( index == lastIndex ) break;
        index += wordIncr;
        if ( word ) carry = 0;
    }

}
Beispiel #21
0
void f128M_to_extF80M( const float128_t *aPtr, extFloat80_t *zPtr )
{
    const uint32_t *aWPtr;
    struct extFloat80M *zSPtr;
    uint32_t uiA96;
    bool sign;
    int32_t exp;
    struct commonNaN commonNaN;
    uint32_t sig[4];

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    zSPtr = (struct extFloat80M *) zPtr;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uiA96 = aWPtr[indexWordHi( 4 )];
    sign = signF128UI96( uiA96 );
    exp  = expF128UI96( uiA96 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp == 0x7FFF ) {
        if ( softfloat_isNaNF128M( aWPtr ) ) {
            softfloat_f128MToCommonNaN( aWPtr, &commonNaN );
            softfloat_commonNaNToExtF80M( &commonNaN, zSPtr );
            return;
        }
        zSPtr->signExp = packToExtF80UI64( sign, 0x7FFF );
        zSPtr->signif = UINT64_C( 0x8000000000000000 );
        return;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    exp = softfloat_shiftNormSigF128M( aWPtr, 15, sig );
    if ( exp == -128 ) {
        zSPtr->signExp = packToExtF80UI64( sign, 0 );
        zSPtr->signif = 0;
        return;
    }
    if ( sig[indexWord( 4, 0 )] ) sig[indexWord( 4, 1 )] |= 1;
    softfloat_roundPackMToExtF80M(
        sign, exp, &sig[indexMultiwordHi( 4, 3 )], 80, zSPtr );

}
Beispiel #22
0
uint_fast64_t
 f128M_to_ui64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;
    bool sign;
    int32_t exp;
    uint32_t sig96;
    int32_t shiftDist;
    uint32_t sig[4];

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    uiA96 = aWPtr[indexWordHi( 4 )];
    sign  = signF128UI96( uiA96 );
    exp   = expF128UI96( uiA96 );
    sig96 = fracF128UI96( uiA96 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    shiftDist = 0x404F - exp;
    if ( shiftDist < 17 ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return
            (exp == 0x7FFF)
                && (sig96
                        || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )]
                                | aWPtr[indexWord( 4, 0 )]))
                ? ui64_fromNaN
                : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp ) sig96 |= 0x00010000;
    sig[indexWord( 4, 3 )] = sig96;
    sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
    sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
    sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
    softfloat_shiftRightJam128M( sig, shiftDist, sig );
    return
        softfloat_roundMToUI64(
            sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact );

}
int softfloat_normSubnormalF128SigM( uint32_t *sigPtr )
{
    const uint32_t *ptr;
    int_fast16_t shiftCount;
    uint32_t wordSig;

    ptr = sigPtr + indexWordHi( 4 );
    shiftCount = 0;
    for (;;) {
        wordSig = *ptr;
        if ( wordSig ) break;
        shiftCount += 32;
        if ( 128 <= shiftCount ) return 1;
        ptr -= wordIncr;
    }
    shiftCount += softfloat_countLeadingZeros32( wordSig ) - 15;
    if ( shiftCount ) softfloat_shiftLeft128M( sigPtr, shiftCount, sigPtr );
    return 1 - shiftCount;

}
Beispiel #24
0
void
 softfloat_add256M(
     const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr )
{
    unsigned int index;
    uint_fast8_t carry;
    uint64_t wordA, wordZ;

    index = indexWordLo( 4 );
    carry = 0;
    for (;;) {
        wordA = aPtr[index];
        wordZ = wordA + bPtr[index] + carry;
        zPtr[index] = wordZ;
        if ( index == indexWordHi( 4 ) ) break;
        if ( wordZ != wordA ) carry = (wordZ < wordA);
        index += wordIncr;
    }

}
Beispiel #25
0
int_fast64_t
 f128M_to_i64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;
    int32_t exp;
    bool sign;
    uint32_t sig96;
    int32_t shiftCount;
    uint32_t sig[4];

    aWPtr = (const uint32_t *) aPtr;
    uiA96 = aWPtr[indexWordHi( 4 )];
    exp = expF128UI96( uiA96 );
    sign  = signF128UI96( uiA96 );
    sig96 = fracF128UI96( uiA96 );
    shiftCount = 0x404F - exp;
    if ( shiftCount < 17 ) {
        softfloat_raiseFlags( softfloat_flag_invalid );
        return
            ! sign
                || ((exp == 0x7FFF)
                        && (sig96
                                || (  aWPtr[indexWord( 4, 2 )]
                                    | aWPtr[indexWord( 4, 1 )]
                                    | aWPtr[indexWord( 4, 0 )]
                                   )))
                ? INT64_C( 0x7FFFFFFFFFFFFFFF )
                : -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;
    }
    if ( exp ) sig96 |= 0x00010000;
    sig[indexWord( 4, 3 )] = sig96;
    sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
    sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
    sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
    softfloat_shiftRightJam128M( sig, shiftCount, sig );
    return
        softfloat_roundPackMToI64(
            sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact );

}
Beispiel #26
0
uint_fast32_t
 f128M_to_ui32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;
    bool sign;
    int32_t exp;
    uint64_t sig64;
    int32_t shiftDist;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    uiA96 = aWPtr[indexWordHi( 4 )];
    sign = signF128UI96( uiA96 );
    exp  = expF128UI96( uiA96 );
    sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )];
    if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
    if ( (exp == 0x7FFF) && sig64 ) {
#if (ui32_fromNaN == ui32_fromPosOverflow)
        sign = 0;
#elif (ui32_fromNaN == ui32_fromNegOverflow)
        sign = 1;
#else
        softfloat_raiseFlags( softfloat_flag_invalid );
        return ui32_fromNaN;
#endif
    }
#endif
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 );
    shiftDist = 0x4028 - exp;
    if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist );
    return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact );

}
Beispiel #27
0
uint_fast32_t
 f128M_to_ui32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
{
    const uint32_t *aWPtr;
    uint32_t uiA96;
    int32_t exp;
    uint64_t sig64;
    int32_t shiftCount;

    aWPtr = (const uint32_t *) aPtr;
    uiA96 = aWPtr[indexWordHi( 4 )];
    exp = expF128UI96( uiA96 );
    sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )];
    if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 );
    if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1;
    shiftCount = 0x4028 - exp;
    if ( 0 < shiftCount ) {
        sig64 = softfloat_shiftRightJam64( sig64, shiftCount );
    }
    return
        softfloat_roundPackToUI32(
            signF128UI96( uiA96 ), sig64, roundingMode, exact );

}
Beispiel #28
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 );

}
Beispiel #29
0
void
 f128M_mul( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
{
    const uint32_t *aWPtr, *bWPtr;
    uint32_t *zWPtr;
    uint32_t uiA96;
    int32_t expA;
    uint32_t uiB96;
    int32_t expB;
    bool signZ;
    const uint32_t *ptr;
    uint32_t uiZ96, sigA[4];
    uint_fast8_t shiftDist;
    uint32_t sigB[4];
    int32_t expZ;
    uint32_t sigProd[8], *extSigZPtr;

    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    aWPtr = (const uint32_t *) aPtr;
    bWPtr = (const uint32_t *) bPtr;
    zWPtr = (uint32_t *) zPtr;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    uiA96 = aWPtr[indexWordHi( 4 )];
    expA = expF128UI96( uiA96 );
    uiB96 = bWPtr[indexWordHi( 4 )];
    expB = expF128UI96( uiB96 );
    signZ = signF128UI96( uiA96 ) ^ signF128UI96( uiB96 );
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) {
        if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return;
        ptr = aWPtr;
        if ( ! expA ) goto possiblyInvalid;
        if ( ! expB ) {
            ptr = bWPtr;
     possiblyInvalid:
            if (
                ! fracF128UI96( ptr[indexWordHi( 4 )] )
                    && ! (ptr[indexWord( 4, 2 )] | ptr[indexWord( 4, 1 )]
                              | ptr[indexWord( 4, 0 )])
            ) {
                softfloat_invalidF128M( zWPtr );
                return;
            }
        }
        uiZ96 = packToF128UI96( signZ, 0x7FFF, 0 );
        goto uiZ96;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    if ( expA ) {
        sigA[indexWordHi( 4 )] = fracF128UI96( uiA96 ) | 0x00010000;
        sigA[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )];
        sigA[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )];
        sigA[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )];
    } else {
        expA = softfloat_shiftNormSigF128M( aWPtr, 0, sigA );
        if ( expA == -128 ) goto zero;
    }
    if ( expB ) {
        sigB[indexWordHi( 4 )] = fracF128UI96( uiB96 ) | 0x00010000;
        sigB[indexWord( 4, 2 )] = bWPtr[indexWord( 4, 2 )];
        sigB[indexWord( 4, 1 )] = bWPtr[indexWord( 4, 1 )];
        sigB[indexWord( 4, 0 )] = bWPtr[indexWord( 4, 0 )];
    } else {
        expB = softfloat_shiftNormSigF128M( bWPtr, 0, sigB );
        if ( expB == -128 ) goto zero;
    }
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
    expZ = expA + expB - 0x4000;
    softfloat_mul128MTo256M( sigA, sigB, sigProd );
    if (
        sigProd[indexWord( 8, 2 )]
            || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )])
    ) {
        sigProd[indexWord( 8, 3 )] |= 1;
    }
    extSigZPtr = &sigProd[indexMultiwordHi( 8, 5 )];
    shiftDist = 16;
    if ( extSigZPtr[indexWordHi( 5 )] & 2 ) {
        ++expZ;
        shiftDist = 15;
    }
    softfloat_shortShiftLeft160M( extSigZPtr, shiftDist, extSigZPtr );
    softfloat_roundPackMToF128M( signZ, expZ, extSigZPtr, zWPtr );
    return;
    /*------------------------------------------------------------------------
    *------------------------------------------------------------------------*/
 zero:
    uiZ96 = packToF128UI96( signZ, 0, 0 );
 uiZ96:
    zWPtr[indexWordHi( 4 )] = uiZ96;
    zWPtr[indexWord( 4, 2 )] = 0;
    zWPtr[indexWord( 4, 1 )] = 0;
    zWPtr[indexWord( 4, 0 )] = 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;

}