|  | @@ -0,0 +1,172 @@
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +===============================================================================
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +This C source file is part of the SoftFloat IEC/IEEE Floating-point
 | 
	
		
			
				|  |  | +Arithmetic Package, Release 2.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Written by John R. Hauser.  This work was made possible in part by the
 | 
	
		
			
				|  |  | +International Computer Science Institute, located at Suite 600, 1947 Center
 | 
	
		
			
				|  |  | +Street, Berkeley, California 94704.  Funding was partially provided by the
 | 
	
		
			
				|  |  | +National Science Foundation under grant MIP-9311980.  The original version
 | 
	
		
			
				|  |  | +of this code was written as part of a project to build a fixed-point vector
 | 
	
		
			
				|  |  | +processor in collaboration with the University of California at Berkeley,
 | 
	
		
			
				|  |  | +overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
 | 
	
		
			
				|  |  | +is available through the web page
 | 
	
		
			
				|  |  | +http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
 | 
	
		
			
				|  |  | +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
 | 
	
		
			
				|  |  | +TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
 | 
	
		
			
				|  |  | +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
 | 
	
		
			
				|  |  | +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Derivative works are acceptable, even for commercial purposes, so long as
 | 
	
		
			
				|  |  | +(1) they include prominent notice that the work is derivative, and (2) they
 | 
	
		
			
				|  |  | +include prominent notice akin to these three paragraphs for those parts of
 | 
	
		
			
				|  |  | +this code that are retained.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +===============================================================================
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <asm/div64.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include "fpa11.h"
 | 
	
		
			
				|  |  | +//#include "milieu.h"
 | 
	
		
			
				|  |  | +//#include "softfloat.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Primitive arithmetic functions, including multi-word arithmetic, and
 | 
	
		
			
				|  |  | +division and square root approximations.  (Can be specialized to target if
 | 
	
		
			
				|  |  | +desired.)
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +#include "softfloat-macros"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Functions and definitions to determine:  (1) whether tininess for underflow
 | 
	
		
			
				|  |  | +is detected before or after rounding by default, (2) what (if anything)
 | 
	
		
			
				|  |  | +happens when exceptions are raised, (3) how signaling NaNs are distinguished
 | 
	
		
			
				|  |  | +from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
 | 
	
		
			
				|  |  | +are propagated from function inputs to output.  These details are target-
 | 
	
		
			
				|  |  | +specific.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +#include "softfloat-specialize"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
 | 
	
		
			
				|  |  | +and 7, and returns the properly rounded 32-bit integer corresponding to the
 | 
	
		
			
				|  |  | +input.  If `zSign' is nonzero, the input is negated before being converted
 | 
	
		
			
				|  |  | +to an integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point
 | 
	
		
			
				|  |  | +input is simply rounded to an integer, with the inexact exception raised if
 | 
	
		
			
				|  |  | +the input cannot be represented exactly as an integer.  If the fixed-point
 | 
	
		
			
				|  |  | +input is too large, however, the invalid exception is raised and the largest
 | 
	
		
			
				|  |  | +positive or negative integer is returned.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    int8 roundingMode;
 | 
	
		
			
				|  |  | +    flag roundNearestEven;
 | 
	
		
			
				|  |  | +    int8 roundIncrement, roundBits;
 | 
	
		
			
				|  |  | +    int32 z;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    roundingMode = roundData->mode;
 | 
	
		
			
				|  |  | +    roundNearestEven = ( roundingMode == float_round_nearest_even );
 | 
	
		
			
				|  |  | +    roundIncrement = 0x40;
 | 
	
		
			
				|  |  | +    if ( ! roundNearestEven ) {
 | 
	
		
			
				|  |  | +        if ( roundingMode == float_round_to_zero ) {
 | 
	
		
			
				|  |  | +            roundIncrement = 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        else {
 | 
	
		
			
				|  |  | +            roundIncrement = 0x7F;
 | 
	
		
			
				|  |  | +            if ( zSign ) {
 | 
	
		
			
				|  |  | +                if ( roundingMode == float_round_up ) roundIncrement = 0;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else {
 | 
	
		
			
				|  |  | +                if ( roundingMode == float_round_down ) roundIncrement = 0;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    roundBits = absZ & 0x7F;
 | 
	
		
			
				|  |  | +    absZ = ( absZ + roundIncrement )>>7;
 | 
	
		
			
				|  |  | +    absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
 | 
	
		
			
				|  |  | +    z = absZ;
 | 
	
		
			
				|  |  | +    if ( zSign ) z = - z;
 | 
	
		
			
				|  |  | +    if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
 | 
	
		
			
				|  |  | +        roundData->exception |= float_flag_invalid;
 | 
	
		
			
				|  |  | +        return zSign ? 0x80000000 : 0x7FFFFFFF;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if ( roundBits ) roundData->exception |= float_flag_inexact;
 | 
	
		
			
				|  |  | +    return z;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the fraction bits of the single-precision floating-point value `a'.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +INLINE bits32 extractFloat32Frac( float32 a )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return a & 0x007FFFFF;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the exponent bits of the single-precision floating-point value `a'.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +INLINE int16 extractFloat32Exp( float32 a )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return ( a>>23 ) & 0xFF;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Returns the sign bit of the single-precision floating-point value `a'.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +#if 0	/* in softfloat.h */
 | 
	
		
			
				|  |  | +INLINE flag extractFloat32Sign( float32 a )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return a>>31;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Normalizes the subnormal single-precision floating-point value represented
 | 
	
		
			
				|  |  | +by the denormalized significand `aSig'.  The normalized exponent and
 | 
	
		
			
				|  |  | +significand are stored at the locations pointed to by `zExpPtr' and
 | 
	
		
			
				|  |  | +`zSigPtr', respectively.
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +static void
 | 
	
		
			
				|  |  | + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    int8 shiftCount;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    shiftCount = countLeadingZeros32( aSig ) - 8;
 | 
	
		
			
				|  |  | +    *zSigPtr = aSig<<shiftCount;
 | 
	
		
			
				|  |  | +    *zExpPtr = 1 - shiftCount;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | +-------------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
 | 
	
		
			
				|  |  | +single-precision floating-point value, returning the result.  After being
 | 
	
		
			
				|  |  | +shifted into the proper positions, the three fields are simply added
 | 
	
		
			
				|  |  | +together to form the result.  This means that any integer portion of `zSig'
 | 
	
		
			
				|  |  | +will be added into the exponent.  Since a properly normalized significand
 | 
	
		
			
				|  |  | +will have an integer portion equal to 1, the `zExp' input should be 1 less
 |