Changeset a96c570 in mainline


Ignore:
Timestamp:
2006-01-22T15:51:00Z (19 years ago)
Author:
Josef Cejka <malyzelenyhnus@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bff16dd
Parents:
4a5abddd
Message:

Added function for 64bit subtraction.
Fixed bug in recognizing signaling and quiet NaNs.
Some 64-bit add and sub testing done.

Location:
softfloat
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • softfloat/generic/add.c

    r4a5abddd ra96c570  
    133133{
    134134        int expdiff;
    135         __u64 exp1, exp2, mant1, mant2;
     135        __u32 exp1, exp2;
     136        __u64 mant1, mant2;
    136137       
    137138        expdiff = a.parts.exp - b.parts.exp;
  • softfloat/generic/comparison.c

    r4a5abddd ra96c570  
    4141
    4242inline int isFloat32SigNaN(float32 f)
    43 {       /* SigNaN : exp = 0xff mantisa = 1xxxxx..x (binary), where at least one x is nonzero */
    44         return ((f.parts.exp==0xFF)&&(f.parts.mantisa>0x400000));
     43{       /* SigNaN : exp = 0xff mantisa = 0xxxxx..x (binary), where at least one x is nonzero */
     44        return ((f.parts.exp==0xFF)&&(f.parts.mantisa<0x400000)&&(f.parts.mantisa));
    4545};
    4646
    4747inline int isFloat64SigNaN(float64 d)
    48 {       /* SigNaN : exp = 0x7ff mantisa = 1xxxxx..x (binary), where at least one x is nonzero */
    49         return ((d.parts.exp==0x7FF)&&(d.parts.mantisa>0x8000000000000ll));
     48{       /* SigNaN : exp = 0x7ff mantisa = 0xxxxx..x (binary), where at least one x is nonzero */
     49        return ((d.parts.exp==0x7FF)&&(d.parts.mantisa)&&(d.parts.mantisa<0x8000000000000ll));
    5050};
    5151
  • softfloat/generic/softfloat.c

    r4a5abddd ra96c570  
    5757}
    5858
     59double __adddf3(double a, double b)
     60{
     61        float64 da, db;
     62        da.d=a;
     63        db.d=b;
     64        if (da.parts.sign!=db.parts.sign) {
     65                if (da.parts.sign) {
     66                        da.parts.sign=0;
     67                        return subFloat64(db,da).d;
     68                };
     69                db.parts.sign=0;
     70                return subFloat64(da,db).d;
     71        }
     72        return addFloat64(da,db).d;
     73}
     74
    5975float __subsf3(float a, float b)
    6076{
     
    6783        }
    6884        return subFloat32(fa,fb).f;
     85}
     86
     87double __subdf3(double a, double b)
     88{
     89        float64 da, db;
     90        da.d = a;
     91        db.d = b;
     92        if (da.parts.sign != db.parts.sign) {
     93                db.parts.sign = !db.parts.sign;
     94                return addFloat64(da, db).d;
     95        }
     96        return subFloat64(da, db).d;
    6997}
    7098
  • softfloat/generic/sub.c

    r4a5abddd ra96c570  
    2727 */
    2828
    29 #include "sftypes.h"
    30 #include "sub.h"
     29#include<sftypes.h>
     30#include<sub.h>
     31#include<comparison.h>
    3132
    3233/** Subtract two float32 numbers with same signs
     
    3536{
    3637        int expdiff;
    37         __u32 exp1,exp2,mant1,mant2;
     38        __u32 exp1, exp2, mant1, mant2;
    3839        float32 result;
    3940
    4041        result.f = 0;
    4142       
    42         expdiff=a.parts.exp - b.parts.exp;
    43         if ((expdiff<0)||((expdiff==0)&&(a.parts.mantisa<b.parts.mantisa))) {
     43        expdiff = a.parts.exp - b.parts.exp;
     44        if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.mantisa < b.parts.mantisa))) {
    4445                if (isFloat32NaN(b)) {
    4546                        //TODO: fix SigNaN
     
    4950                };
    5051               
    51                 if (b.parts.exp==0xFF) {
    52                         b.parts.sign=!b.parts.sign; /* num -(+-inf) = -+inf */
     52                if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
     53                        b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */
    5354                        return b;
    5455                }
     
    5657                result.parts.sign = !a.parts.sign;
    5758               
    58                 mant1=b.parts.mantisa;
    59                 exp1=b.parts.exp;
    60                 mant2=a.parts.mantisa;
    61                 exp2=a.parts.exp;
    62                 expdiff*=-1;
     59                mant1 = b.parts.mantisa;
     60                exp1 = b.parts.exp;
     61                mant2 = a.parts.mantisa;
     62                exp2 = a.parts.exp;
     63                expdiff *= -1;
    6364        } else {
    6465                if (isFloat32NaN(a)) {
    6566                        //TODO: fix SigNaN
    66                         if ((isFloat32SigNaN(a))||(isFloat32SigNaN(b))) {
    67                         };
    68                         return a;
    69                 };
    70                
    71                 if (a.parts.exp==0xFF) {
    72                         if (b.parts.exp==0xFF) {
     67                        if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
     68                        };
     69                        return a;
     70                };
     71               
     72                if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
     73                        if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
    7374                                /* inf - inf => nan */
    7475                                //TODO: fix exception
     
    8182                result.parts.sign = a.parts.sign;
    8283               
    83                 mant1=a.parts.mantisa;
    84                 exp1=a.parts.exp;
    85                 mant2=b.parts.mantisa;
    86                 exp2=b.parts.exp;       
    87         };
    88        
    89         if (exp1==0) {
     84                mant1 = a.parts.mantisa;
     85                exp1 = a.parts.exp;
     86                mant2 = b.parts.mantisa;
     87                exp2 = b.parts.exp;     
     88        };
     89       
     90        if (exp1 == 0) {
    9091                //both are denormalized
    91                 result.parts.mantisa=mant1-mant2;
    92                 if (result.parts.mantisa>mant1) {
     92                result.parts.mantisa = mant1-mant2;
     93                if (result.parts.mantisa > mant1) {
    9394                        //TODO: underflow exception
    9495                        return result;
    9596                };
    96                 result.parts.exp=0;
     97                result.parts.exp = 0;
    9798                return result;
    9899        };
    99        
    100         // create some space for rounding
    101         mant1<<=6;
    102         mant2<<=6;
    103        
    104         mant1|=0x20000000; //add hidden bit
    105        
    106        
    107         if (exp2==0) {
     100
     101        /* add hidden bit */
     102        mant1 |= FLOAT32_HIDDEN_BIT_MASK;
     103       
     104        if (exp2 == 0) {
     105                /* denormalized */
    108106                --expdiff;     
    109107        } else {
    110                 mant2|=0x20000000; //hidden bit
    111         };
    112        
    113         if (expdiff>24) {
     108                /* normalized */
     109                mant2 |= FLOAT32_HIDDEN_BIT_MASK;
     110        };
     111       
     112        /* create some space for rounding */
     113        mant1 <<= 6;
     114        mant2 <<= 6;
     115       
     116        if (expdiff > FLOAT32_MANTISA_SIZE + 1) {
    114117             goto done;
    115118             };
    116119       
    117         mant1 = mant1-(mant2>>expdiff);
     120        mant1 = mant1 - (mant2 >> expdiff);
    118121done:
    119122        //TODO: find first nonzero digit and shift result and detect possibly underflow
    120         while ((exp1>0)&&(!(mant1&0x20000000))) {
    121                 exp1--;
     123        while ((exp1 > 0) && (!(mant1 & (FLOAT32_HIDDEN_BIT_MASK << 6 )))) {
     124                --exp1;
    122125                mant1 <<= 1;
    123126                        /* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */
    124127        };
    125128       
    126         //rounding - if first bit after mantisa is set then round up   
     129        /* rounding - if first bit after mantisa is set then round up */
    127130        mant1 += 0x20;
    128131
    129         if (mant1&0x40000000) {
     132        if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
    130133                ++exp1;
    131                 mant1>>=1;
    132         };
    133        
    134         result.parts.mantisa = ((mant1&(~0x20000000))>>6); /*Clear hidden bit and shift */
     134                mant1 >>= 1;
     135        };
     136       
     137        /*Clear hidden bit and shift */
     138        result.parts.mantisa = ((mant1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
    135139        result.parts.exp = exp1;
    136140       
    137141        return result;
    138 };
    139 
     142}
     143
     144/** Subtract two float64 numbers with same signs
     145 */
     146float64 subFloat64(float64 a, float64 b)
     147{
     148        int expdiff;
     149        __u32 exp1, exp2;
     150        __u64 mant1, mant2;
     151        float64 result;
     152
     153        result.d = 0;
     154       
     155        expdiff = a.parts.exp - b.parts.exp;
     156        if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.mantisa < b.parts.mantisa))) {
     157                if (isFloat64NaN(b)) {
     158                        //TODO: fix SigNaN
     159                        if (isFloat64SigNaN(b)) {
     160                        };
     161                        return b;
     162                };
     163               
     164                if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
     165                        b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */
     166                        return b;
     167                }
     168               
     169                result.parts.sign = !a.parts.sign;
     170               
     171                mant1 = b.parts.mantisa;
     172                exp1 = b.parts.exp;
     173                mant2 = a.parts.mantisa;
     174                exp2 = a.parts.exp;
     175                expdiff *= -1;
     176        } else {
     177                if (isFloat64NaN(a)) {
     178                        //TODO: fix SigNaN
     179                        if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
     180                        };
     181                        return a;
     182                };
     183               
     184                if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
     185                        if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
     186                                /* inf - inf => nan */
     187                                //TODO: fix exception
     188                                result.binary = FLOAT64_NAN;
     189                                return result;
     190                        };
     191                        return a;
     192                }
     193               
     194                result.parts.sign = a.parts.sign;
     195               
     196                mant1 = a.parts.mantisa;
     197                exp1 = a.parts.exp;
     198                mant2 = b.parts.mantisa;
     199                exp2 = b.parts.exp;     
     200        };
     201       
     202        if (exp1 == 0) {
     203                //both are denormalized
     204                result.parts.mantisa = mant1 - mant2;
     205                if (result.parts.mantisa > mant1) {
     206                        //TODO: underflow exception
     207                        return result;
     208                };
     209                result.parts.exp = 0;
     210                return result;
     211        };
     212
     213        /* add hidden bit */
     214        mant1 |= FLOAT64_HIDDEN_BIT_MASK;
     215       
     216        if (exp2 == 0) {
     217                /* denormalized */
     218                --expdiff;     
     219        } else {
     220                /* normalized */
     221                mant2 |= FLOAT64_HIDDEN_BIT_MASK;
     222        };
     223       
     224        /* create some space for rounding */
     225        mant1 <<= 6;
     226        mant2 <<= 6;
     227       
     228        if (expdiff > FLOAT64_MANTISA_SIZE + 1) {
     229             goto done;
     230             };
     231       
     232        mant1 = mant1 - (mant2 >> expdiff);
     233done:
     234        //TODO: find first nonzero digit and shift result and detect possibly underflow
     235        while ((exp1 > 0) && (!(mant1 & (FLOAT64_HIDDEN_BIT_MASK << 6 )))) {
     236                --exp1;
     237                mant1 <<= 1;
     238                        /* TODO: fix underflow - mant1 == 0 does not necessary means underflow... */
     239        };
     240       
     241        /* rounding - if first bit after mantisa is set then round up */
     242        mant1 += 0x20;
     243
     244        if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
     245                ++exp1;
     246                mant1 >>= 1;
     247        };
     248       
     249        /*Clear hidden bit and shift */
     250        result.parts.mantisa = ((mant1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
     251        result.parts.exp = exp1;
     252       
     253        return result;
     254}
     255
  • softfloat/include/sftypes.h

    r4a5abddd ra96c570  
    7474
    7575/* For recognizing NaNs or infinity use isFloat32NaN and is Float32Inf, comparing with this constants is not sufficient */
    76 #define FLOAT32_NAN 0x7F800001
    77 #define FLOAT32_SIGNAN 0x7FC00000
     76#define FLOAT32_NAN 0x7FC00001
     77#define FLOAT32_SIGNAN 0x7F800001
    7878#define FLOAT32_INF 0x7F800000
     79
     80#define FLOAT64_NAN 0x7FF8000000000001ll
     81#define FLOAT64_SIGNAN 0x7FF0000000000001ll
     82#define FLOAT64_INF 0x7FF0000000000000ll
    7983
    8084#define FLOAT32_MANTISA_SIZE 23
     
    8589
    8690#define FLOAT32_MAX_EXPONENT 0xFF
    87 #define FLOAT64_MAX_EXPONENT 0x8FF
     91#define FLOAT64_MAX_EXPONENT 0x7FF
    8892
    8993#define FLOAT32_BIAS 0x7F
  • softfloat/include/sub.h

    r4a5abddd ra96c570  
    3232float32 subFloat32(float32 a, float32 b);
    3333
     34float64 subFloat64(float64 a, float64 b);
     35
    3436#endif
    3537
Note: See TracChangeset for help on using the changeset viewer.