foo

来自「基于4个mips核的noc设计」· 代码 · 共 1,873 行 · 第 1/5 页

TXT
1,873
字号
INLINE void mul32To64( bits32 a, bits32 b, bits32 *z0Ptr, bits32 *z1Ptr ){    bits16 aHigh, aLow, bHigh, bLow;    bits32 z0, zMiddleA, zMiddleB, z1;    aLow = a;    aHigh = a>>16;    bLow = b;    bHigh = b>>16;#ifdef __minimips    aLow &= 0xffff;    bLow &= 0xffff;    aHigh &= 0xffff;    bHigh &= 0xffff;#endif    z1 = ( (bits32) aLow ) * bLow;    zMiddleA = ( (bits32) aLow ) * bHigh;    zMiddleB = ( (bits32) aHigh ) * bLow;    z0 = ( (bits32) aHigh ) * bHigh;    zMiddleA += zMiddleB;    z0 += ( ( (bits32) ( zMiddleA < zMiddleB ) )<<16 ) + ( zMiddleA>>16 );    zMiddleA <<= 16;    z1 += zMiddleA;    z0 += ( z1 < zMiddleA );    *z1Ptr = z1;    *z0Ptr = z0;}/*----------------------------------------------------------------------------| Multiplies the 64-bit value formed by concatenating `a0' and `a1' by `b'| to obtain a 96-bit product.  The product is broken into three 32-bit pieces| which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and| `z2Ptr'.*----------------------------------------------------------------------------*/INLINE void mul64By32To96(     bits32 a0,     bits32 a1,     bits32 b,     bits32 *z0Ptr,     bits32 *z1Ptr,     bits32 *z2Ptr ){    bits32 z0, z1, z2, more1;    mul32To64( a1, b, &z1, &z2 );    mul32To64( a0, b, &z0, &more1 );    add64( z0, more1, 0, z1, &z0, &z1 );    *z2Ptr = z2;    *z1Ptr = z1;    *z0Ptr = z0;}/*----------------------------------------------------------------------------| Multiplies the 64-bit value formed by concatenating `a0' and `a1' to the| 64-bit value formed by concatenating `b0' and `b1' to obtain a 128-bit| product.  The product is broken into four 32-bit pieces which are stored at| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.*----------------------------------------------------------------------------*/INLINE void mul64To128(     bits32 a0,     bits32 a1,     bits32 b0,     bits32 b1,     bits32 *z0Ptr,     bits32 *z1Ptr,     bits32 *z2Ptr,     bits32 *z3Ptr ){    bits32 z0, z1, z2, z3;    bits32 more1, more2;    mul32To64( a1, b1, &z2, &z3 );    mul32To64( a1, b0, &z1, &more2 );    add64( z1, more2, 0, z2, &z1, &z2 );    mul32To64( a0, b0, &z0, &more1 );    add64( z0, more1, 0, z1, &z0, &z1 );    mul32To64( a0, b1, &more1, &more2 );    add64( more1, more2, 0, z2, &more1, &z2 );    add64( z0, z1, 0, more1, &z0, &z1 );    *z3Ptr = z3;    *z2Ptr = z2;    *z1Ptr = z1;    *z0Ptr = z0;}/*----------------------------------------------------------------------------| Returns an approximation to the 32-bit integer quotient obtained by dividing| `b' into the 64-bit value formed by concatenating `a0' and `a1'.  The| divisor `b' must be at least 2^31.  If q is the exact quotient truncated| toward zero, the approximation returned lies between q and q + 2 inclusive.| If the exact quotient q is larger than 32 bits, the maximum positive 32-bit| unsigned integer is returned.*----------------------------------------------------------------------------*/static bits32 estimateDiv64To32( bits32 a0, bits32 a1, bits32 b ){    bits32 b0, b1;    bits32 rem0, rem1, term0, term1;    bits32 z;    if ( b <= a0 ) return 0xFFFFFFFF;    b0 = b>>16;    z = ( b0<<16 <= a0 ) ? 0xFFFF0000 : ( a0 / b0 )<<16;    mul32To64( b, z, &term0, &term1 );    sub64( a0, a1, term0, term1, &rem0, &rem1 );    while ( ( (sbits32) rem0 ) < 0 ) {        z -= 0x10000;        b1 = b<<16;        add64( rem0, rem1, b0, b1, &rem0, &rem1 );    }    rem0 = ( rem0<<16 ) | ( rem1>>16 );    z |= ( b0<<16 <= rem0 ) ? 0xFFFF : rem0 / b0;    return z;}/*----------------------------------------------------------------------------| Returns an approximation to the square root of the 32-bit significand given| by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of| `aExp' (the least significant bit) is 1, the integer returned approximates| 2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either| case, the approximation returned lies strictly within +/-2 of the exact| value.*----------------------------------------------------------------------------*/static bits32 estimateSqrt32( int16 aExp, bits32 a ){    static const bits16 sqrtOddAdjustments[] = {        0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,        0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67    };    static const bits16 sqrtEvenAdjustments[] = {        0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,        0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002    };    int8 index;    bits32 z;    index = ( a>>27 ) & 15;    if ( aExp & 1 ) {        z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];        z = ( ( a / z )<<14 ) + ( z<<15 );        a >>= 1;    }    else {        z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];        z = a / z + z;        z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );        if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );    }    return ( ( estimateDiv64To32( a, 0, z ) )>>1 ) + ( z>>1 );}/*----------------------------------------------------------------------------| Returns the number of leading 0 bits before the most-significant 1 bit of| `a'.  If `a' is zero, 32 is returned.*----------------------------------------------------------------------------*/static int8 countLeadingZeros32( bits32 a ){    static const int8 countLeadingZerosHigh[] = {        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0    };    int8 shiftCount;    shiftCount = 0;    if ( a < 0x10000 ) {        shiftCount += 16;        a <<= 16;    }    if ( a < 0x1000000 ) {        shiftCount += 8;        a <<= 8;    }    shiftCount += countLeadingZerosHigh[ a>>24 ];    return shiftCount;}/*----------------------------------------------------------------------------| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is| equal to the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,| returns 0.*----------------------------------------------------------------------------*/INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ){    return ( a0 == b0 ) && ( a1 == b1 );}/*----------------------------------------------------------------------------| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less| than or equal to the 64-bit value formed by concatenating `b0' and `b1'.| Otherwise, returns 0.*----------------------------------------------------------------------------*/INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ){    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );}/*----------------------------------------------------------------------------| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less| than the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,| returns 0.*----------------------------------------------------------------------------*/INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ){    return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );}/*----------------------------------------------------------------------------| Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is not| equal to the 64-bit value formed by concatenating `b0' and `b1'.  Otherwise,| returns 0.*----------------------------------------------------------------------------*/INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ){    return ( a0 != b0 ) || ( a1 != b1 );}/*============================================================================This C source file is part of the SoftFloat IEC/IEEE Floating-point ArithmeticPackage, Release 2b.Written by John R. Hauser.  This work was made possible in part by theInternational Computer Science Institute, located at Suite 600, 1947 CenterStreet, Berkeley, California 94704.  Funding was partially provided by theNational Science Foundation under grant MIP-9311980.  The original versionof this code was written as part of a project to build a fixed-point vectorprocessor in collaboration with the University of California at Berkeley,overseen by Profs. Nelson Morgan and John Wawrzynek.  More informationis available through the Web page `http://www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html'.THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort hasbeen made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMESRESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONSAND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMOREEFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCEINSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OROTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.Derivative works are acceptable, even for commercial purposes, so long as(1) the source code for the derivative work includes prominent notice thatthe work is derivative, and (2) the source code includes prominent notice withthese four paragraphs for those parts of this code that are retained.=============================================================================*/#include "milieu.h"#include "softfloat.h"/*----------------------------------------------------------------------------| Floating-point rounding mode and exception flags.*----------------------------------------------------------------------------*/char float_rounding_mode = float_round_nearest_even;char float_exception_flags = 0;/*----------------------------------------------------------------------------| 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 (4) how NaNs| are propagated from function inputs to output.  These details are target-| specific.*----------------------------------------------------------------------------*/#include "softfloat-specialize"/*----------------------------------------------------------------------------| 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'.*----------------------------------------------------------------------------*/INLINE flag extractFloat32Sign( float32 a ){    return a>>31;}/*----------------------------------------------------------------------------| 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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?