Changeset a96c570 in mainline for softfloat/generic/sub.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.