Changeset bff16dd in mainline


Ignore:
Timestamp:
2006-01-22T17:59:13Z (19 years ago)
Author:
Josef Cejka <malyzelenyhnus@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2b34a88
Parents:
a96c570
Message:

Added function for 64 bit multiplication but its still buggy.

Location:
softfloat
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • softfloat/generic/mul.c

    ra96c570 rbff16dd  
    4242        result.parts.sign = a.parts.sign ^ b.parts.sign;
    4343       
    44         if ((isFloat32NaN(a))||(isFloat32NaN(b))) {
     44        if (isFloat32NaN(a) || isFloat32NaN(b) ) {
    4545                /* TODO: fix SigNaNs */
    4646                if (isFloat32SigNaN(a)) {
     
    5555                };
    5656                /* set NaN as result */
    57                 result.parts.mantisa = 0x1;
    58                 result.parts.exp = 0xFF;
     57                result.binary = FLOAT32_NAN;
    5958                return result;
    6059        };
     
    6362                if (isFloat32Zero(b)) {
    6463                        /* FIXME: zero * infinity */
    65                         result.parts.mantisa = 0x1;
    66                         result.parts.exp = 0xFF;
     64                        result.binary = FLOAT32_NAN;
    6765                        return result;
    6866                }
     
    7573                if (isFloat32Zero(a)) {
    7674                        /* FIXME: zero * infinity */
    77                         result.parts.mantisa = 0x1;
    78                         result.parts.exp = 0xFF;
     75                        result.binary = FLOAT32_NAN;
    7976                        return result;
    8077                }
     
    8885        exp -= FLOAT32_BIAS;
    8986       
    90         if (exp >= 0xFF ) {
     87        if (exp >= FLOAT32_MAX_EXPONENT) {
    9188                /* FIXME: overflow */
    9289                /* set infinity as result */
    93                 result.parts.mantisa = 0x0;
    94                 result.parts.exp = 0xFF;
     90                result.binary = FLOAT32_INF;
     91                result.parts.sign = a.parts.sign ^ b.parts.sign;
    9592                return result;
    9693        };
     
    105102       
    106103        mant1 = a.parts.mantisa;
    107         if (a.parts.exp>0) {
    108                 mant1 |= 0x800000;
     104        if (a.parts.exp > 0) {
     105                mant1 |= FLOAT32_HIDDEN_BIT_MASK;
    109106        } else {
    110107                ++exp;
     
    112109       
    113110        mant2 = b.parts.mantisa;
    114         if (b.parts.exp>0) {
    115                 mant2 |= 0x800000;
     111
     112        if (b.parts.exp > 0) {
     113                mant2 |= FLOAT32_HIDDEN_BIT_MASK;
    116114        } else {
    117115                ++exp;
     
    123121/* round and return */
    124122       
    125         while ((exp < 0xFF )&&(mant1 > 0x1FFFFFF )) {
    126                 /* 0xFFFFFF is 23 bits of mantisa + one more for hidden bit (all shifted 1 bit left)*/
     123        while ((exp < FLOAT32_MAX_EXPONENT) && (mant1 >= ( 1 << (FLOAT32_MANTISA_SIZE + 2)))) {
     124                /* 23 bits of mantisa + one more for hidden bit (all shifted 1 bit left)*/
    127125                ++exp;
    128126                mant1 >>= 1;
     
    133131        mant1 >>= 1; /* shift off rounding space */
    134132       
    135         if ((exp < 0xFF )&&(mant1 > 0xFFFFFF )) {
    136                 ++exp;
    137                 mant1 >>= 1;
    138         };
    139 
    140         if (exp >= 0xFF ) {     
     133        if ((exp < FLOAT32_MAX_EXPONENT) && (mant1 >= (1 << (FLOAT32_MANTISA_SIZE + 1)))) {
     134                ++exp;
     135                mant1 >>= 1;
     136        };
     137
     138        if (exp >= FLOAT32_MAX_EXPONENT ) {     
    141139                /* TODO: fix overflow */
    142140                /* return infinity*/
    143                 result.parts.exp = 0xFF;
     141                result.parts.exp = FLOAT32_MAX_EXPONENT;
    144142                result.parts.mantisa = 0x0;
    145143                return result;
     
    163161        };
    164162        result.parts.exp = exp;
    165         result.parts.mantisa = mant1 & 0x7FFFFF;
     163        result.parts.mantisa = mant1 & ( (1 << FLOAT32_MANTISA_SIZE) - 1);
    166164       
    167165        return result; 
     
    169167}
    170168
    171 
    172 
     169/** Multiply two 64 bit float numbers
     170 *
     171 */
     172float64 mulFloat64(float64 a, float64 b)
     173{
     174        float64 result;
     175        __u64 mant1, mant2;
     176        __s32 exp;
     177
     178        result.parts.sign = a.parts.sign ^ b.parts.sign;
     179       
     180        if (isFloat64NaN(a) || isFloat64NaN(b) ) {
     181                /* TODO: fix SigNaNs */
     182                if (isFloat64SigNaN(a)) {
     183                        result.parts.mantisa = a.parts.mantisa;
     184                        result.parts.exp = a.parts.exp;
     185                        return result;
     186                };
     187                if (isFloat64SigNaN(b)) { /* TODO: fix SigNaN */
     188                        result.parts.mantisa = b.parts.mantisa;
     189                        result.parts.exp = b.parts.exp;
     190                        return result;
     191                };
     192                /* set NaN as result */
     193                result.binary = FLOAT64_NAN;
     194                return result;
     195        };
     196               
     197        if (isFloat64Infinity(a)) {
     198                if (isFloat64Zero(b)) {
     199                        /* FIXME: zero * infinity */
     200                        result.binary = FLOAT64_NAN;
     201                        return result;
     202                }
     203                result.parts.mantisa = a.parts.mantisa;
     204                result.parts.exp = a.parts.exp;
     205                return result;
     206        }
     207
     208        if (isFloat64Infinity(b)) {
     209                if (isFloat64Zero(a)) {
     210                        /* FIXME: zero * infinity */
     211                        result.binary = FLOAT64_NAN;
     212                        return result;
     213                }
     214                result.parts.mantisa = b.parts.mantisa;
     215                result.parts.exp = b.parts.exp;
     216                return result;
     217        }
     218
     219        /* exp is signed so we can easy detect underflow */
     220        exp = a.parts.exp + b.parts.exp;
     221        exp -= FLOAT64_BIAS;
     222       
     223        if (exp >= FLOAT64_MAX_EXPONENT) {
     224                /* FIXME: overflow */
     225                /* set infinity as result */
     226                result.binary = FLOAT64_INF;
     227                result.parts.sign = a.parts.sign ^ b.parts.sign;
     228                return result;
     229        };
     230       
     231        if (exp < 0) {
     232                /* FIXME: underflow */
     233                /* return signed zero */
     234                result.parts.mantisa = 0x0;
     235                result.parts.exp = 0x0;
     236                return result;
     237        };
     238       
     239        mant1 = a.parts.mantisa;
     240        if (a.parts.exp > 0) {
     241                mant1 |= FLOAT64_HIDDEN_BIT_MASK;
     242        } else {
     243                ++exp;
     244        };
     245       
     246        mant2 = b.parts.mantisa;
     247
     248        if (b.parts.exp > 0) {
     249                mant2 |= FLOAT64_HIDDEN_BIT_MASK;
     250        } else {
     251                ++exp;
     252        };
     253
     254        mant1 <<= 1; /* one bit space for rounding */
     255
     256        mul64integers(mant1, mant2, &mant1, &mant2);
     257
     258/* round and return */
     259        /* FIXME: ugly soulution is to shift whole mant2 >> as in 32bit version
     260         * Here is is more slower because we have to shift two numbers with carry
     261         * Better is find first nonzero bit and make only one shift
     262         * Third version is to shift both numbers a bit to right and result will be then
     263         * placed in higher part of result. Then lower part will be good only for rounding.
     264         */
     265       
     266        while ((exp < FLOAT64_MAX_EXPONENT) && (mant2 > 0 )) {
     267                mant1 >>= 1;
     268                mant1 &= ((mant2 & 0x1) << 63);
     269                mant2 >>= 1;
     270                ++exp;
     271        }
     272       
     273        while ((exp < FLOAT64_MAX_EXPONENT) && (mant1 >= ( (__u64)1 << (FLOAT64_MANTISA_SIZE + 2)))) {
     274                ++exp;
     275                mant1 >>= 1;
     276        };
     277
     278        /* rounding */
     279        //++mant1; /* FIXME: not works - without it is ok */
     280        mant1 >>= 1; /* shift off rounding space */
     281       
     282        if ((exp < FLOAT64_MAX_EXPONENT) && (mant1 >= ((__u64)1 << (FLOAT64_MANTISA_SIZE + 1)))) {
     283                ++exp;
     284                mant1 >>= 1;
     285        };
     286
     287        if (exp >= FLOAT64_MAX_EXPONENT ) {     
     288                /* TODO: fix overflow */
     289                /* return infinity*/
     290                result.parts.exp = FLOAT64_MAX_EXPONENT;
     291                result.parts.mantisa = 0x0;
     292                return result;
     293        }
     294       
     295        exp -= FLOAT64_MANTISA_SIZE;
     296
     297        if (exp <= FLOAT64_MANTISA_SIZE) {
     298                /* denormalized number */
     299                mant1 >>= 1; /* denormalize */
     300                while ((mant1 > 0) && (exp < 0)) {
     301                        mant1 >>= 1;
     302                        ++exp;
     303                };
     304                if (mant1 == 0) {
     305                        /* FIXME : underflow */
     306                result.parts.exp = 0;
     307                result.parts.mantisa = 0;
     308                return result;
     309                };
     310        };
     311        result.parts.exp = exp;
     312        result.parts.mantisa = mant1 & ( ((__u64)1 << FLOAT64_MANTISA_SIZE) - 1);
     313       
     314        return result; 
     315       
     316}
     317
     318/** Multiply two 64 bit numbers and return result in two parts
     319 * @param a first operand
     320 * @param b second operand
     321 * @param lo lower part from result
     322 * @param hi higher part of result
     323 */
     324void mul64integers(__u64 a,__u64 b, __u64 *lo, __u64 *hi)
     325{
     326        __u64 low, high, middle1, middle2;
     327        __u32 alow, blow;
     328       
     329        alow = a & 0xFFFFFFFF;
     330        blow = b & 0xFFFFFFFF;
     331       
     332        a <<= 32;
     333        b <<= 32;
     334       
     335        low = (__u64)alow * blow;
     336        middle1 = a * blow;
     337        middle2 = alow * b;
     338        high = a * b;
     339
     340        middle1 += middle2;
     341        high += ((__u64)(middle1 < middle2) << 32) + middle1>>32;
     342        middle1 << 32;
     343        low += middle1;
     344        high += (low < middle1);
     345        *lo = low;
     346        *hi = high;
     347        return;
     348}
     349
     350
  • softfloat/generic/softfloat.c

    ra96c570 rbff16dd  
    105105}
    106106
     107double __muldf3(double a, double b)
     108{
     109        float64 da, db;
     110        da.d = a;
     111        db.d = b;
     112        return  mulFloat64(da, db).d;
     113}
     114
    107115float __divsf3(float a, float b)
    108116{
  • softfloat/include/mul.h

    ra96c570 rbff16dd  
    3232float32 mulFloat32(float32 a, float32 b);
    3333
     34float64 mulFloat64(float64 a, float64 b);
     35
     36void mul64integers(__u64 a,__u64 b, __u64 *lo, __u64 *hi);
     37
    3438#endif
    3539
Note: See TracChangeset for help on using the changeset viewer.