|  | @@ -1066,3 +1066,196 @@ static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float3
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          shift32RightJamming( aSig, - expDiff, &aSig );
 | 
	
		
			
				|  |  |          zExp = bExp;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +        if ( aExp == 0xFF ) {
 | 
	
		
			
				|  |  | +            if ( aSig | bSig ) return propagateFloat32NaN( a, b );
 | 
	
		
			
				|  |  | +            return a;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
 | 
	
		
			
				|  |  | +        zSig = 0x40000000 + aSig + bSig;
 | 
	
		
			
				|  |  | +        zExp = aExp;
 | 
	
		
			
				|  |  | +        goto roundAndPack;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    aSig |= 0x20000000;
 | 
	
		
			
				|  |  | +    zSig = ( aSig + bSig )<<1;
 | 
	
		
			
				|  |  | +    --zExp;
 | 
	
		
			
				|  |  | +    if ( (sbits32) zSig < 0 ) {
 | 
	
		
			
				|  |  | +        zSig = aSig + bSig;
 | 
	
		
			
				|  |  | +        ++zExp;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | + roundAndPack:
 | 
	
		
			
				|  |  | +    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the result of subtracting the absolute values of the single-
 | 
	
		
			
				|  |  | +precision floating-point values `a' and `b'.  If `zSign' is true, the
 | 
	
		
			
				|  |  | +difference is negated before being returned.  `zSign' is ignored if the
 | 
	
		
			
				|  |  | +result is a NaN.  The subtraction is performed according to the IEC/IEEE
 | 
	
		
			
				|  |  | +Standard for Binary Floating-point Arithmetic.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    int16 aExp, bExp, zExp;
 | 
	
		
			
				|  |  | +    bits32 aSig, bSig, zSig;
 | 
	
		
			
				|  |  | +    int16 expDiff;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    aSig = extractFloat32Frac( a );
 | 
	
		
			
				|  |  | +    aExp = extractFloat32Exp( a );
 | 
	
		
			
				|  |  | +    bSig = extractFloat32Frac( b );
 | 
	
		
			
				|  |  | +    bExp = extractFloat32Exp( b );
 | 
	
		
			
				|  |  | +    expDiff = aExp - bExp;
 | 
	
		
			
				|  |  | +    aSig <<= 7;
 | 
	
		
			
				|  |  | +    bSig <<= 7;
 | 
	
		
			
				|  |  | +    if ( 0 < expDiff ) goto aExpBigger;
 | 
	
		
			
				|  |  | +    if ( expDiff < 0 ) goto bExpBigger;
 | 
	
		
			
				|  |  | +    if ( aExp == 0xFF ) {
 | 
	
		
			
				|  |  | +        if ( aSig | bSig ) return propagateFloat32NaN( a, b );
 | 
	
		
			
				|  |  | +        roundData->exception |= float_flag_invalid;
 | 
	
		
			
				|  |  | +        return float32_default_nan;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( aExp == 0 ) {
 | 
	
		
			
				|  |  | +        aExp = 1;
 | 
	
		
			
				|  |  | +        bExp = 1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( bSig < aSig ) goto aBigger;
 | 
	
		
			
				|  |  | +    if ( aSig < bSig ) goto bBigger;
 | 
	
		
			
				|  |  | +    return packFloat32( roundData->mode == float_round_down, 0, 0 );
 | 
	
		
			
				|  |  | + bExpBigger:
 | 
	
		
			
				|  |  | +    if ( bExp == 0xFF ) {
 | 
	
		
			
				|  |  | +        if ( bSig ) return propagateFloat32NaN( a, b );
 | 
	
		
			
				|  |  | +        return packFloat32( zSign ^ 1, 0xFF, 0 );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( aExp == 0 ) {
 | 
	
		
			
				|  |  | +        ++expDiff;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +        aSig |= 0x40000000;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    shift32RightJamming( aSig, - expDiff, &aSig );
 | 
	
		
			
				|  |  | +    bSig |= 0x40000000;
 | 
	
		
			
				|  |  | + bBigger:
 | 
	
		
			
				|  |  | +    zSig = bSig - aSig;
 | 
	
		
			
				|  |  | +    zExp = bExp;
 | 
	
		
			
				|  |  | +    zSign ^= 1;
 | 
	
		
			
				|  |  | +    goto normalizeRoundAndPack;
 | 
	
		
			
				|  |  | + aExpBigger:
 | 
	
		
			
				|  |  | +    if ( aExp == 0xFF ) {
 | 
	
		
			
				|  |  | +        if ( aSig ) return propagateFloat32NaN( a, b );
 | 
	
		
			
				|  |  | +        return a;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( bExp == 0 ) {
 | 
	
		
			
				|  |  | +        --expDiff;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +        bSig |= 0x40000000;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    shift32RightJamming( bSig, expDiff, &bSig );
 | 
	
		
			
				|  |  | +    aSig |= 0x40000000;
 | 
	
		
			
				|  |  | + aBigger:
 | 
	
		
			
				|  |  | +    zSig = aSig - bSig;
 | 
	
		
			
				|  |  | +    zExp = aExp;
 | 
	
		
			
				|  |  | + normalizeRoundAndPack:
 | 
	
		
			
				|  |  | +    --zExp;
 | 
	
		
			
				|  |  | +    return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the result of adding the single-precision floating-point values `a'
 | 
	
		
			
				|  |  | +and `b'.  The operation is performed according to the IEC/IEEE Standard for
 | 
	
		
			
				|  |  | +Binary Floating-point Arithmetic.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    flag aSign, bSign;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    aSign = extractFloat32Sign( a );
 | 
	
		
			
				|  |  | +    bSign = extractFloat32Sign( b );
 | 
	
		
			
				|  |  | +    if ( aSign == bSign ) {
 | 
	
		
			
				|  |  | +        return addFloat32Sigs( roundData, a, b, aSign );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +        return subFloat32Sigs( roundData, a, b, aSign );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the result of subtracting the single-precision floating-point values
 | 
	
		
			
				|  |  | +`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 | 
	
		
			
				|  |  | +for Binary Floating-point Arithmetic.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    flag aSign, bSign;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    aSign = extractFloat32Sign( a );
 | 
	
		
			
				|  |  | +    bSign = extractFloat32Sign( b );
 | 
	
		
			
				|  |  | +    if ( aSign == bSign ) {
 | 
	
		
			
				|  |  | +        return subFloat32Sigs( roundData, a, b, aSign );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +        return addFloat32Sigs( roundData, a, b, aSign );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the result of multiplying the single-precision floating-point values
 | 
	
		
			
				|  |  | +`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
 | 
	
		
			
				|  |  | +for Binary Floating-point Arithmetic.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    flag aSign, bSign, zSign;
 | 
	
		
			
				|  |  | +    int16 aExp, bExp, zExp;
 | 
	
		
			
				|  |  | +    bits32 aSig, bSig;
 | 
	
		
			
				|  |  | +    bits64 zSig64;
 | 
	
		
			
				|  |  | +    bits32 zSig;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    aSig = extractFloat32Frac( a );
 | 
	
		
			
				|  |  | +    aExp = extractFloat32Exp( a );
 | 
	
		
			
				|  |  | +    aSign = extractFloat32Sign( a );
 | 
	
		
			
				|  |  | +    bSig = extractFloat32Frac( b );
 | 
	
		
			
				|  |  | +    bExp = extractFloat32Exp( b );
 | 
	
		
			
				|  |  | +    bSign = extractFloat32Sign( b );
 | 
	
		
			
				|  |  | +    zSign = aSign ^ bSign;
 | 
	
		
			
				|  |  | +    if ( aExp == 0xFF ) {
 | 
	
		
			
				|  |  | +        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
 | 
	
		
			
				|  |  | +            return propagateFloat32NaN( a, b );
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if ( ( bExp | bSig ) == 0 ) {
 | 
	
		
			
				|  |  | +            roundData->exception |= float_flag_invalid;
 | 
	
		
			
				|  |  | +            return float32_default_nan;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return packFloat32( zSign, 0xFF, 0 );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( bExp == 0xFF ) {
 | 
	
		
			
				|  |  | +        if ( bSig ) return propagateFloat32NaN( a, b );
 | 
	
		
			
				|  |  | +        if ( ( aExp | aSig ) == 0 ) {
 | 
	
		
			
				|  |  | +            roundData->exception |= float_flag_invalid;
 | 
	
		
			
				|  |  | +            return float32_default_nan;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return packFloat32( zSign, 0xFF, 0 );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( aExp == 0 ) {
 | 
	
		
			
				|  |  | +        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
 | 
	
		
			
				|  |  | +        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( bExp == 0 ) {
 | 
	
		
			
				|  |  | +        if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
 | 
	
		
			
				|  |  | +        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    zExp = aExp + bExp - 0x7F;
 | 
	
		
			
				|  |  | +    aSig = ( aSig | 0x00800000 )<<7;
 |