kernels/linux-2.4.0/arch/arm/nwfpe/softfloat.c
/*
-------------------------------------------------------------------------------
Returns the remainder of the quadruple-precision floating-point value `a'
with respect to the corresponding value `b'.  The operation is performed
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
Returns the remainder of the quadruple-precision floating-point value `a'
with respect to the corresponding value `b'.  The operation is performed
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
Returns the remainder of the quadruple - precision floating - point value ` a ' with respect to the corresponding value ` b ' . The operation is performed according to the IEC / IEEE Standard for Binary Floating - point Arithmetic .
float128 float128_rem( float128 a, float128 b )
{
    flag aSign, bSign, zSign;
    int32 aExp, bExp, expDiff;
    bits64 aSig0, aSig1, bSig0, bSig1;
    bits64 q, term0, term1, term2, allZero, alternateASig0, alternateASig1;
    bits64 sigMean1;
    sbits64 sigMean0;
    float128 z;
    aSig1 = extractFloat128Frac1( a );
    aSig0 = extractFloat128Frac0( a );
    aExp = extractFloat128Exp( a );
    aSign = extractFloat128Sign( a );
    bSig1 = extractFloat128Frac1( b );
    bSig0 = extractFloat128Frac0( b );
    bExp = extractFloat128Exp( b );
    bSign = extractFloat128Sign( b );
    if ( aExp == 0x7FFF ) {
        if (    ( aSig0 | aSig1 )
             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
            return propagateFloat128NaN( a, b );
        }
        goto invalid;
    }
    if ( bExp == 0x7FFF ) {
        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
        return a;
    }
    if ( bExp == 0 ) {
        if ( ( bSig0 | bSig1 ) == 0 ) {
 invalid:
            float_raise( float_flag_invalid );
            z.low = float128_default_nan_low;
            z.high = float128_default_nan_high;
            return z;
        }
        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
    }
    if ( aExp == 0 ) {
        if ( ( aSig0 | aSig1 ) == 0 ) return a;
        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
    }
    expDiff = aExp - bExp;
    if ( expDiff < -1 ) return a;
    shortShift128Left(
        aSig0 | LIT64( 0x0001000000000000 ),
        aSig1,
        15 - ( expDiff < 0 ),
        &aSig0,
        &aSig1
    );
    shortShift128Left(
        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
    q = le128( bSig0, bSig1, aSig0, aSig1 );
    if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
    expDiff -= 64;
    while ( 0 < expDiff ) {
        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
        q = ( 4 < q ) ? q - 4 : 0;
        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
        shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
        shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
        sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
        expDiff -= 61;
    }
    if ( -64 < expDiff ) {
        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
        q = ( 4 < q ) ? q - 4 : 0;
        q >>= - expDiff;
        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
        expDiff += 52;
        if ( expDiff < 0 ) {
            shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
        }
        else {
            shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
        }
        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
        sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
    }
    else {
        shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
    }
    do {
        alternateASig0 = aSig0;
        alternateASig1 = aSig1;
        ++q;
        sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
    } while ( 0 <= (sbits64) aSig0 );
    add128(
        aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
    if (    ( sigMean0 < 0 )
         || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
        aSig0 = alternateASig0;
        aSig1 = alternateASig1;
    }
    zSign = ( (sbits64) aSig0 < 0 );
    if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
    return
        normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 );
}
float128 float128_rem ( float128 a , float128 b ) { flag aSign , bSign , zSign ; int32 aExp , bExp , expDiff ; bits64 aSig0 , aSig1 , bSig0 , bSig1 ; bits64 q , term0 , term1 , term2 , allZero , alternateASig0 , alternateASig1 ; bits64 sigMean1 ; sbits64 sigMean0 ; float128 z ; aSig1 = extractFloat128Frac1 ( a ) ; aSig0 = extractFloat128Frac0 ( a ) ; aExp = extractFloat128Exp ( a ) ; aSign = extractFloat128Sign ( a ) ; bSig1 = extractFloat128Frac1 ( b ) ; bSig0 = extractFloat128Frac0 ( b ) ; bExp = extractFloat128Exp ( b ) ; bSign = extractFloat128Sign ( b ) ; if ( aExp == 0x7FFF ) { if ( ( aSig0 | aSig1 ) || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { return propagateFloat128NaN ( a , b ) ; } goto invalid ; } if ( bExp == 0x7FFF ) { if ( bSig0 | bSig1 ) return propagateFloat128NaN ( a , b ) ; return a ; } if ( bExp == 0 ) { if ( ( bSig0 | bSig1 ) == 0 ) { invalid : float_raise ( float_flag_invalid ) ; z . low = float128_default_nan_low ; z . high = float128_default_nan_high ; return z ; } normalizeFloat128Subnormal ( bSig0 , bSig1 , & bExp , & bSig0 , & bSig1 ) ; } if ( aExp == 0 ) { if ( ( aSig0 | aSig1 ) == 0 ) return a ; normalizeFloat128Subnormal ( aSig0 , aSig1 , & aExp , & aSig0 , & aSig1 ) ; } expDiff = aExp - bExp ; if ( expDiff < -1 ) return a ; shortShift128Left ( aSig0 | LIT64 ( 0x0001000000000000 ) , aSig1 , 15 - ( expDiff < 0 ) , & aSig0 , & aSig1 ) ; shortShift128Left ( bSig0 | LIT64 ( 0x0001000000000000 ) , bSig1 , 15 , & bSig0 , & bSig1 ) ; q = le128 ( bSig0 , bSig1 , aSig0 , aSig1 ) ; if ( q ) sub128 ( aSig0 , aSig1 , bSig0 , bSig1 , & aSig0 , & aSig1 ) ; expDiff -= 64 ; while ( 0 < expDiff ) { q = estimateDiv128To64 ( aSig0 , aSig1 , bSig0 ) ; q = ( 4 < q ) ? q - 4 : 0 ; mul128By64To192 ( bSig0 , bSig1 , q , & term0 , & term1 , & term2 ) ; shortShift192Left ( term0 , term1 , term2 , 61 , & term1 , & term2 , & allZero ) ; shortShift128Left ( aSig0 , aSig1 , 61 , & aSig0 , & allZero ) ; sub128 ( aSig0 , 0 , term1 , term2 , & aSig0 , & aSig1 ) ; expDiff -= 61 ; } if ( -64 < expDiff ) { q = estimateDiv128To64 ( aSig0 , aSig1 , bSig0 ) ; q = ( 4 < q ) ? q - 4 : 0 ; q >>= - expDiff ; shift128Right ( bSig0 , bSig1 , 12 , & bSig0 , & bSig1 ) ; expDiff += 52 ; if ( expDiff < 0 ) { shift128Right ( aSig0 , aSig1 , - expDiff , & aSig0 , & aSig1 ) ; } else { shortShift128Left ( aSig0 , aSig1 , expDiff , & aSig0 , & aSig1 ) ; } mul128By64To192 ( bSig0 , bSig1 , q , & term0 , & term1 , & term2 ) ; sub128 ( aSig0 , aSig1 , term1 , term2 , & aSig0 , & aSig1 ) ; } else { shift128Right ( aSig0 , aSig1 , 12 , & aSig0 , & aSig1 ) ; shift128Right ( bSig0 , bSig1 , 12 , & bSig0 , & bSig1 ) ; } do { alternateASig0 = aSig0 ; alternateASig1 = aSig1 ; ++ q ; sub128 ( aSig0 , aSig1 , bSig0 , bSig1 , & aSig0 , & aSig1 ) ; } while ( 0 <= ( sbits64 ) aSig0 ) ; add128 ( aSig0 , aSig1 , alternateASig0 , alternateASig1 , & sigMean0 , & sigMean1 ) ; if ( ( sigMean0 < 0 ) || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { aSig0 = alternateASig0 ; aSig1 = alternateASig1 ; } zSign = ( ( sbits64 ) aSig0 < 0 ) ; if ( zSign ) sub128 ( 0 , 0 , aSig0 , aSig1 , & aSig0 , & aSig1 ) ; return normalizeRoundAndPackFloat128 ( aSign ^ zSign , bExp - 4 , aSig0 , aSig1 ) ; }
Returns the remainder of the quadruple-precision floating-point value `a'
with respect to the corresponding value `b'.
Returns the remainder of the quadruple - precision floating - point value ` a ' with respect to the corresponding value ` b ' .