Changeset 9b0a6b4 in mainline for uspace/lib/softfloat/generic/sub.c


Ignore:
Timestamp:
2012-04-13T06:36:25Z (12 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
90f067d9
Parents:
e61aa80 (diff), d11a181 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/softfloat/generic/sub.c

    re61aa80 r9b0a6b4  
    3939#include <common.h>
    4040
    41 /**
    42  * Subtract two single-precision floats with the same signs.
     41/** Subtract two single-precision floats with the same sign.
    4342 *
    4443 * @param a First input operand.
    4544 * @param b Second input operand.
     45 *
    4646 * @return Result of substraction.
    47  */
    48 float32 subFloat32(float32 a, float32 b)
     47 *
     48 */
     49float32 sub_float32(float32 a, float32 b)
    4950{
    5051        int expdiff;
    5152        uint32_t exp1, exp2, frac1, frac2;
    5253        float32 result;
    53 
    54         result.f = 0;
     54       
     55        result.bin = 0;
    5556       
    5657        expdiff = a.parts.exp - b.parts.exp;
    57         if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
    58                 if (isFloat32NaN(b)) {
    59                         /* TODO: fix SigNaN */
    60                         if (isFloat32SigNaN(b)) {
    61                         }
    62                         return b;
    63                 }
    64                
    65                 if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
    66                         b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */
    67                         return b;
    68                 }
    69                
    70                 result.parts.sign = !a.parts.sign;
     58        if ((expdiff < 0 ) || ((expdiff == 0) &&
     59            (a.parts.fraction < b.parts.fraction))) {
     60                if (is_float32_nan(b)) {
     61                        if (is_float32_signan(b)) {
     62                                // TODO: fix SigNaN
     63                        }
     64                       
     65                        return b;
     66                }
     67               
     68                if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
     69                        /* num -(+-inf) = -+inf */
     70                        b.parts.sign = !b.parts.sign;
     71                        return b;
     72                }
     73               
     74                result.parts.sign = !a.parts.sign;
    7175               
    7276                frac1 = b.parts.fraction;
     
    7680                expdiff *= -1;
    7781        } else {
    78                 if (isFloat32NaN(a)) {
    79                         /* TODO: fix SigNaN */
    80                         if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
    81                         }
    82                         return a;
    83                 }
    84                
    85                 if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
     82                if (is_float32_nan(a)) {
     83                        if ((is_float32_signan(a)) || (is_float32_signan(b))) {
     84                                // TODO: fix SigNaN
     85                        }
     86                       
     87                        return a;
     88                }
     89               
     90                if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
    8691                        if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
    8792                                /* inf - inf => nan */
    88                                 /* TODO: fix exception */
    89                                 result.binary = FLOAT32_NAN;
     93                                // TODO: fix exception
     94                                result.bin = FLOAT32_NAN;
    9095                                return result;
    9196                        }
     97                       
    9298                        return a;
    9399                }
     
    98104                exp1 = a.parts.exp;
    99105                frac2 = b.parts.fraction;
    100                 exp2 = b.parts.exp;     
     106                exp2 = b.parts.exp;
    101107        }
    102108       
     
    105111                result.parts.fraction = frac1 - frac2;
    106112                if (result.parts.fraction > frac1) {
    107                         /* TODO: underflow exception */
     113                        // TODO: underflow exception
    108114                        return result;
    109115                }
     116               
    110117                result.parts.exp = 0;
    111118                return result;
    112119        }
    113 
     120       
    114121        /* add hidden bit */
    115         frac1 |= FLOAT32_HIDDEN_BIT_MASK; 
     122        frac1 |= FLOAT32_HIDDEN_BIT_MASK;
    116123       
    117124        if (exp2 == 0) {
    118125                /* denormalized */
    119                 --expdiff;     
     126                --expdiff;
    120127        } else {
    121128                /* normalized */
     
    127134        frac2 <<= 6;
    128135       
    129         if (expdiff > FLOAT32_FRACTION_SIZE + 1) {
     136        if (expdiff > FLOAT32_FRACTION_SIZE + 1)
    130137                goto done;
    131         }
    132138       
    133139        frac1 = frac1 - (frac2 >> expdiff);
    134 
     140       
    135141done:
    136142        /* TODO: find first nonzero digit and shift result and detect possibly underflow */
     
    143149        /* rounding - if first bit after fraction is set then round up */
    144150        frac1 += 0x20;
    145 
     151       
    146152        if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
    147153                ++exp1;
     
    150156       
    151157        /* Clear hidden bit and shift */
    152         result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 
     158        result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
    153159        result.parts.exp = exp1;
    154160       
     
    156162}
    157163
    158 /**
    159  * Subtract two double-precision floats with the same signs.
     164/** Subtract two double-precision floats with the same sign.
    160165 *
    161166 * @param a First input operand.
    162167 * @param b Second input operand.
     168 *
    163169 * @return Result of substraction.
    164  */
    165 float64 subFloat64(float64 a, float64 b)
     170 *
     171 */
     172float64 sub_float64(float64 a, float64 b)
    166173{
    167174        int expdiff;
     
    169176        uint64_t frac1, frac2;
    170177        float64 result;
    171 
    172         result.d = 0;
     178       
     179        result.bin = 0;
    173180       
    174181        expdiff = a.parts.exp - b.parts.exp;
    175         if ((expdiff < 0 ) || ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
    176                 if (isFloat64NaN(b)) {
    177                         /* TODO: fix SigNaN */
    178                         if (isFloat64SigNaN(b)) {
    179                         }
    180                         return b;
    181                 }
    182                
    183                 if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
    184                         b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */
    185                         return b;
    186                 }
    187                
    188                 result.parts.sign = !a.parts.sign;
     182        if ((expdiff < 0 ) ||
     183            ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
     184                if (is_float64_nan(b)) {
     185                        if (is_float64_signan(b)) {
     186                                // TODO: fix SigNaN
     187                        }
     188                       
     189                        return b;
     190                }
     191               
     192                if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
     193                        /* num -(+-inf) = -+inf */
     194                        b.parts.sign = !b.parts.sign;
     195                        return b;
     196                }
     197               
     198                result.parts.sign = !a.parts.sign;
    189199               
    190200                frac1 = b.parts.fraction;
     
    194204                expdiff *= -1;
    195205        } else {
    196                 if (isFloat64NaN(a)) {
    197                         /* TODO: fix SigNaN */
    198                         if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
    199                         }
    200                         return a;
    201                 }
    202                
    203                 if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
     206                if (is_float64_nan(a)) {
     207                        if (is_float64_signan(a) || is_float64_signan(b)) {
     208                                // TODO: fix SigNaN
     209                        }
     210                       
     211                        return a;
     212                }
     213               
     214                if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
    204215                        if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
    205216                                /* inf - inf => nan */
    206                                 /* TODO: fix exception */
    207                                 result.binary = FLOAT64_NAN;
     217                                // TODO: fix exception
     218                                result.bin = FLOAT64_NAN;
    208219                                return result;
    209220                        }
     221                       
    210222                        return a;
    211223                }
     
    216228                exp1 = a.parts.exp;
    217229                frac2 = b.parts.fraction;
    218                 exp2 = b.parts.exp;     
     230                exp2 = b.parts.exp;
    219231        }
    220232       
     
    223235                result.parts.fraction = frac1 - frac2;
    224236                if (result.parts.fraction > frac1) {
    225                         /* TODO: underflow exception */
     237                        // TODO: underflow exception
    226238                        return result;
    227239                }
     240               
    228241                result.parts.exp = 0;
    229242                return result;
    230243        }
    231 
     244       
    232245        /* add hidden bit */
    233         frac1 |= FLOAT64_HIDDEN_BIT_MASK; 
     246        frac1 |= FLOAT64_HIDDEN_BIT_MASK;
    234247       
    235248        if (exp2 == 0) {
    236249                /* denormalized */
    237                 --expdiff;     
     250                --expdiff;
    238251        } else {
    239252                /* normalized */
     
    245258        frac2 <<= 6;
    246259       
    247         if (expdiff > FLOAT64_FRACTION_SIZE + 1) {
     260        if (expdiff > FLOAT64_FRACTION_SIZE + 1)
    248261                goto done;
    249         }
    250262       
    251263        frac1 = frac1 - (frac2 >> expdiff);
    252 
     264       
    253265done:
    254266        /* TODO: find first nonzero digit and shift result and detect possibly underflow */
     
    261273        /* rounding - if first bit after fraction is set then round up */
    262274        frac1 += 0x20;
    263 
     275       
    264276        if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
    265277                ++exp1;
     
    268280       
    269281        /* Clear hidden bit and shift */
    270         result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK)); 
     282        result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
    271283        result.parts.exp = exp1;
    272284       
     
    274286}
    275287
    276 /**
    277  * Subtract two quadruple-precision floats with the same signs.
     288/** Subtract two quadruple-precision floats with the same sign.
    278289 *
    279290 * @param a First input operand.
    280291 * @param b Second input operand.
     292 *
    281293 * @return Result of substraction.
    282  */
    283 float128 subFloat128(float128 a, float128 b)
     294 *
     295 */
     296float128 sub_float128(float128 a, float128 b)
    284297{
    285298        int expdiff;
     
    287300        uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
    288301        float128 result;
    289 
    290         result.binary.hi = 0;
    291         result.binary.lo = 0;
    292 
     302       
     303        result.bin.hi = 0;
     304        result.bin.lo = 0;
     305       
    293306        expdiff = a.parts.exp - b.parts.exp;
    294307        if ((expdiff < 0 ) || ((expdiff == 0) &&
    295308            lt128(a.parts.frac_hi, a.parts.frac_lo, b.parts.frac_hi, b.parts.frac_lo))) {
    296                 if (isFloat128NaN(b)) {
    297                         /* TODO: fix SigNaN */
    298                         if (isFloat128SigNaN(b)) {
    299                         }
    300                         return b;
    301                 }
    302 
     309                if (is_float128_nan(b)) {
     310                        if (is_float128_signan(b)) {
     311                                // TODO: fix SigNaN
     312                        }
     313                       
     314                        return b;
     315                }
     316               
    303317                if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
    304                         b.parts.sign = !b.parts.sign; /* num -(+-inf) = -+inf */
    305                         return b;
    306                 }
    307 
     318                        /* num -(+-inf) = -+inf */
     319                        b.parts.sign = !b.parts.sign;
     320                        return b;
     321                }
     322               
    308323                result.parts.sign = !a.parts.sign;
    309 
     324               
    310325                frac1_hi = b.parts.frac_hi;
    311326                frac1_lo = b.parts.frac_lo;
     
    316331                expdiff *= -1;
    317332        } else {
    318                 if (isFloat128NaN(a)) {
    319                         /* TODO: fix SigNaN */
    320                         if (isFloat128SigNaN(a) || isFloat128SigNaN(b)) {
    321                         }
    322                         return a;
    323                 }
    324 
     333                if (is_float128_nan(a)) {
     334                        if (is_float128_signan(a) || is_float128_signan(b)) {
     335                                // TODO: fix SigNaN
     336                        }
     337                       
     338                        return a;
     339                }
     340               
    325341                if (a.parts.exp == FLOAT128_MAX_EXPONENT) {
    326342                        if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
    327343                                /* inf - inf => nan */
    328                                 /* TODO: fix exception */
    329                                 result.binary.hi = FLOAT128_NAN_HI;
    330                                 result.binary.lo = FLOAT128_NAN_LO;
     344                                // TODO: fix exception
     345                                result.bin.hi = FLOAT128_NAN_HI;
     346                                result.bin.lo = FLOAT128_NAN_LO;
    331347                                return result;
    332348                        }
    333349                        return a;
    334350                }
    335 
     351               
    336352                result.parts.sign = a.parts.sign;
    337 
     353               
    338354                frac1_hi = a.parts.frac_hi;
    339355                frac1_lo = a.parts.frac_lo;
     
    343359                exp2 = b.parts.exp;
    344360        }
    345 
     361       
    346362        if (exp1 == 0) {
    347363                /* both are denormalized */
     
    350366                result.parts.frac_lo = tmp_lo;
    351367                if (lt128(frac1_hi, frac1_lo, result.parts.frac_hi, result.parts.frac_lo)) {
    352                         /* TODO: underflow exception */
     368                        // TODO: underflow exception
    353369                        return result;
    354370                }
     371               
    355372                result.parts.exp = 0;
    356373                return result;
    357374        }
    358 
     375       
    359376        /* add hidden bit */
    360377        or128(frac1_hi, frac1_lo,
    361378            FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
    362379            &frac1_hi, &frac1_lo);
    363 
     380       
    364381        if (exp2 == 0) {
    365382                /* denormalized */
     
    371388                    &frac2_hi, &frac2_lo);
    372389        }
    373 
     390       
    374391        /* create some space for rounding */
    375392        lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
    376393        lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo);
    377 
    378         if (expdiff > FLOAT128_FRACTION_SIZE + 1) {
     394       
     395        if (expdiff > FLOAT128_FRACTION_SIZE + 1)
    379396                goto done;
    380         }
    381 
     397       
    382398        rshift128(frac2_hi, frac2_lo, expdiff, &tmp_hi, &tmp_lo);
    383399        sub128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo);
    384 
     400       
    385401done:
    386402        /* TODO: find first nonzero digit and shift result and detect possibly underflow */
     
    392408                lshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
    393409                /* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
    394 
     410               
    395411                lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6,
    396412                    &tmp_hi, &tmp_lo);
    397413                and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
    398414        }
    399 
     415       
    400416        /* rounding - if first bit after fraction is set then round up */
    401417        add128(frac1_hi, frac1_lo, 0x0ll, 0x20ll, &frac1_hi, &frac1_lo);
    402 
     418       
    403419        lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
    404420           &tmp_hi, &tmp_lo);
     
    408424                rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
    409425        }
    410 
     426       
    411427        /* Clear hidden bit and shift */
    412428        rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
     
    416432        result.parts.frac_hi = tmp_hi;
    417433        result.parts.frac_lo = tmp_lo;
    418 
     434       
    419435        result.parts.exp = exp1;
    420 
     436       
    421437        return result;
    422438}
Note: See TracChangeset for help on using the changeset viewer.