123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /*
- ===============================================================================
- 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
|