Changeset e979fea in mainline for softfloat/generic/mul.c


Ignore:
Timestamp:
2006-02-10T13:43:41Z (19 years ago)
Author:
Josef Cejka <malyzelenyhnus@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d3ca210
Parents:
e6a40ac
Message:

Fixed some problems with 64 bit arithmetic but others still persisting.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • softfloat/generic/mul.c

    re6a40ac re979fea  
    3030#include<mul.h>
    3131#include<comparison.h>
     32#include<common.h>
    3233
    3334/** Multiply two 32 bit float numbers
     
    218219
    219220        /* 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.fraction = 0x0;
    235                 result.parts.exp = 0x0;
    236                 return result;
    237         };
     221        exp = a.parts.exp + b.parts.exp - FLOAT64_BIAS;
    238222       
    239223        frac1 = a.parts.fraction;
     224
    240225        if (a.parts.exp > 0) {
    241226                frac1 |= FLOAT64_HIDDEN_BIT_MASK;
     
    252237        };
    253238
    254         frac1 <<= 1; /* one bit space for rounding */
     239        frac1 <<= (64 - FLOAT64_FRACTION_SIZE - 1);
     240        frac2 <<= (64 - FLOAT64_FRACTION_SIZE - 2);
    255241
    256242        mul64integers(frac1, frac2, &frac1, &frac2);
    257243
    258 /* round and return */
    259         /* FIXME: ugly soulution is to shift whole frac2 >> 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) && (frac2 > 0 )) {
    267                 frac1 >>= 1;
    268                 frac1 &= ((frac2 & 0x1) << 63);
    269                 frac2 >>= 1;
    270                 ++exp;
    271         }
    272        
    273         while ((exp < FLOAT64_MAX_EXPONENT) && (frac1 >= ( (__u64)1 << (FLOAT64_FRACTION_SIZE + 2)))) {
    274                 ++exp;
    275                 frac1 >>= 1;
    276         };
    277 
    278         /* rounding */
    279         /* ++frac1;  FIXME: not works - without it is ok */
    280         frac1 >>= 1; /* shift off rounding space */
    281        
    282         if ((exp < FLOAT64_MAX_EXPONENT) && (frac1 >= ((__u64)1 << (FLOAT64_FRACTION_SIZE + 1)))) {
    283                 ++exp;
    284                 frac1 >>= 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.fraction = 0x0;
    292                 return result;
    293         }
    294        
    295         exp -= FLOAT64_FRACTION_SIZE;
    296 
    297         if (exp <= FLOAT64_FRACTION_SIZE) {
    298                 /* denormalized number */
    299                 frac1 >>= 1; /* denormalize */
    300                 while ((frac1 > 0) && (exp < 0)) {
    301                         frac1 >>= 1;
    302                         ++exp;
    303                 };
    304                 if (frac1 == 0) {
    305                         /* FIXME : underflow */
    306                 result.parts.exp = 0;
    307                 result.parts.fraction = 0;
    308                 return result;
    309                 };
    310         };
    311         result.parts.exp = exp;
    312         result.parts.fraction = frac1 & ( ((__u64)1 << FLOAT64_FRACTION_SIZE) - 1);
    313        
    314         return result; 
    315        
     244        frac2 |= (frac1 != 0);
     245        if (frac2 & (0x1ll << 62)) {
     246                frac2 <<= 1;
     247                exp--;
     248        }
     249
     250        result = finishFloat64(exp, frac2, result.parts.sign);
     251        return result;
    316252}
    317253
     
    326262        __u64 low, high, middle1, middle2;
    327263        __u32 alow, blow;
    328        
     264
    329265        alow = a & 0xFFFFFFFF;
    330266        blow = b & 0xFFFFFFFF;
Note: See TracChangeset for help on using the changeset viewer.