Ignore:
Timestamp:
2011-08-06T07:04:50Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d3e241a, e0e922d
Parents:
9a6034a
Message:

Quadruple-precision softfloat, coding style improvements. Details below…

Highlights:

  • completed double-precision support
  • added quadruple-precision support
  • added SPARC quadruple-precision wrappers
  • added doxygen comments
  • corrected and unified coding style

Current state of the softfloat library:

Support for single, double and quadruple precision is currently almost complete (apart from power, square root, complex multiplication and complex division) and provides the same set of features (i.e. the support for all three precisions is now aligned). In order to extend softfloat library consistently, addition of quadruple precision was done in the same spirit as already existing single and double precision written by Josef Cejka in 2006 - that is relaxed standard-compliance for corner cases while mission-critical code sections heavily inspired by the widely used softfloat library written by John R. Hauser (although I personally think it would be more appropriate for HelenOS to use something less optimized, shorter and more readable).

Most of the quadruple-precision code is just an adapted double-precision code to work on 128-bit variables. That means if there is TODO, FIXME or some defect in single or double-precision code, it is most likely also in the quadruple-precision code. Please note that quadruple-precision functions are currently not tested - it is challenging task for itself, especially when the ports that use them are either not finished (mips64) or badly supported by simulators (sparc64). To test whole softfloat library, one would probably have to either write very non-trivial native tester, or use some existing one (e.g. TestFloat from J. R. Hauser) and port it to HelenOS (or rip the softfloat library out of HelenOS and test it on a host system). At the time of writing this, the code dependent on quadruple-precision functions (on mips64 and sparc64) is just a libposix strtold() function (and its callers, most notably scanf backend).

File:
1 edited

Legend:

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

    r9a6034a rc67aff2  
    11/*
    22 * Copyright (c) 2005 Josef Cejka
     3 * Copyright (c) 2011 Petr Koupy
    34 * All rights reserved.
    45 *
     
    3031 * @{
    3132 */
    32 /** @file
    33  */
    34 
    35 #include "sftypes.h"
    36 #include "conversion.h"
    37 #include "comparison.h"
    38 #include "common.h"
     33/** @file Conversion of precision and conversion between integers and floats.
     34 */
     35
     36#include <sftypes.h>
     37#include <conversion.h>
     38#include <comparison.h>
     39#include <common.h>
    3940
    4041float64 convertFloat32ToFloat64(float32 a)
     
    4849       
    4950        if ((isFloat32Infinity(a)) || (isFloat32NaN(a))) {
    50                 result.parts.exp = 0x7FF;
     51                result.parts.exp = FLOAT64_MAX_EXPONENT;
    5152                /* TODO; check if its correct for SigNaNs*/
    5253                return result;
    53         };
     54        }
    5455       
    5556        result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
     
    5758                /* normalize denormalized numbers */
    5859
    59                 if (result.parts.fraction == 0ll) { /* fix zero */
    60                         result.parts.exp = 0ll;
     60                if (result.parts.fraction == 0) { /* fix zero */
     61                        result.parts.exp = 0;
    6162                        return result;
    6263                }
     
    6465                frac = result.parts.fraction;
    6566               
    66                 while (!(frac & (0x10000000000000ll))) {
     67                while (!(frac & FLOAT64_HIDDEN_BIT_MASK)) {
    6768                        frac <<= 1;
    6869                        --result.parts.exp;
    69                 };
     70                }
    7071               
    7172                ++result.parts.exp;
    7273                result.parts.fraction = frac;
    73         };
    74        
    75         return result;
    76        
     74        }
     75       
     76        return result;
     77}
     78
     79float128 convertFloat32ToFloat128(float32 a)
     80{
     81        float128 result;
     82        uint64_t frac_hi, frac_lo;
     83        uint64_t tmp_hi, tmp_lo;
     84
     85        result.parts.sign = a.parts.sign;
     86        result.parts.frac_hi = 0;
     87        result.parts.frac_lo = a.parts.fraction;
     88        lshift128(result.parts.frac_hi, result.parts.frac_lo,
     89            (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE),
     90            &frac_hi, &frac_lo);
     91        result.parts.frac_hi = frac_hi;
     92        result.parts.frac_lo = frac_lo;
     93
     94        if ((isFloat32Infinity(a)) || (isFloat32NaN(a))) {
     95                result.parts.exp = FLOAT128_MAX_EXPONENT;
     96                /* TODO; check if its correct for SigNaNs*/
     97                return result;
     98        }
     99
     100        result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT32_BIAS);
     101        if (a.parts.exp == 0) {
     102                /* normalize denormalized numbers */
     103
     104                if (eq128(result.parts.frac_hi,
     105                    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
     106                        result.parts.exp = 0;
     107                        return result;
     108                }
     109
     110                frac_hi = result.parts.frac_hi;
     111                frac_lo = result.parts.frac_lo;
     112
     113                and128(frac_hi, frac_lo,
     114                    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
     115                    &tmp_hi, &tmp_lo);
     116                while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
     117                        lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
     118                        --result.parts.exp;
     119                }
     120
     121                ++result.parts.exp;
     122                result.parts.frac_hi = frac_hi;
     123                result.parts.frac_lo = frac_lo;
     124        }
     125
     126        return result;
     127}
     128
     129float128 convertFloat64ToFloat128(float64 a)
     130{
     131        float128 result;
     132        uint64_t frac_hi, frac_lo;
     133        uint64_t tmp_hi, tmp_lo;
     134
     135        result.parts.sign = a.parts.sign;
     136        result.parts.frac_hi = 0;
     137        result.parts.frac_lo = a.parts.fraction;
     138        lshift128(result.parts.frac_hi, result.parts.frac_lo,
     139            (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE),
     140            &frac_hi, &frac_lo);
     141        result.parts.frac_hi = frac_hi;
     142        result.parts.frac_lo = frac_lo;
     143
     144        if ((isFloat64Infinity(a)) || (isFloat64NaN(a))) {
     145                result.parts.exp = FLOAT128_MAX_EXPONENT;
     146                /* TODO; check if its correct for SigNaNs*/
     147                return result;
     148        }
     149
     150        result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT64_BIAS);
     151        if (a.parts.exp == 0) {
     152                /* normalize denormalized numbers */
     153
     154                if (eq128(result.parts.frac_hi,
     155                    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
     156                        result.parts.exp = 0;
     157                        return result;
     158                }
     159
     160                frac_hi = result.parts.frac_hi;
     161                frac_lo = result.parts.frac_lo;
     162
     163                and128(frac_hi, frac_lo,
     164                    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
     165                    &tmp_hi, &tmp_lo);
     166                while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
     167                        lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
     168                        --result.parts.exp;
     169                }
     170
     171                ++result.parts.exp;
     172                result.parts.frac_hi = frac_hi;
     173                result.parts.frac_lo = frac_lo;
     174        }
     175
     176        return result;
    77177}
    78178
     
    86186       
    87187        if (isFloat64NaN(a)) {
    88                
    89                 result.parts.exp = 0xFF;
     188                result.parts.exp = FLOAT32_MAX_EXPONENT;
    90189               
    91190                if (isFloat64SigNaN(a)) {
    92                         result.parts.fraction = 0x400000; /* set first bit of fraction nonzero */
     191                        /* set first bit of fraction nonzero */
     192                        result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
    93193                        return result;
    94194                }
    95        
    96                 result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
    97                 return result;
    98         };
     195
     196                /* fraction nonzero but its first bit is zero */
     197                result.parts.fraction = 0x1;
     198                return result;
     199        }
    99200
    100201        if (isFloat64Infinity(a)) {
    101202                result.parts.fraction = 0;
    102                 result.parts.exp = 0xFF;
    103                 return result;
    104         };
    105 
    106         exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
    107        
    108         if (exp >= 0xFF) {
    109                 /*FIXME: overflow*/
     203                result.parts.exp = FLOAT32_MAX_EXPONENT;
     204                return result;
     205        }
     206
     207        exp = (int) a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
     208       
     209        if (exp >= FLOAT32_MAX_EXPONENT) {
     210                /* FIXME: overflow */
    110211                result.parts.fraction = 0;
    111                 result.parts.exp = 0xFF;
    112                 return result;
    113                
    114         } else if (exp <= 0 ) {
    115                
     212                result.parts.exp = FLOAT32_MAX_EXPONENT;
     213                return result;
     214        } else if (exp <= 0) {
    116215                /* underflow or denormalized */
    117216               
     
    119218               
    120219                exp *= -1;     
    121                 if (exp > FLOAT32_FRACTION_SIZE ) {
     220                if (exp > FLOAT32_FRACTION_SIZE) {
    122221                        /* FIXME: underflow */
    123222                        result.parts.fraction = 0;
    124223                        return result;
    125                 };
     224                }
    126225               
    127226                /* denormalized */
    128227               
    129228                frac = a.parts.fraction;
    130                 frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
     229                frac |= FLOAT64_HIDDEN_BIT_MASK; /* denormalize and set hidden bit */
    131230               
    132231                frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
     
    135234                        --exp;
    136235                        frac >>= 1;
    137                 };
     236                }
    138237                result.parts.fraction = frac;
    139238               
    140239                return result;
    141         };
     240        }
    142241
    143242        result.parts.exp = exp;
    144         result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
    145         return result;
    146 }
    147 
    148 
    149 /** Helping procedure for converting float32 to uint32
    150  * @param a floating point number in normalized form (no NaNs or Inf are checked )
    151  * @return unsigned integer
     243        result.parts.fraction =
     244            a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
     245        return result;
     246}
     247
     248float32 convertFloat128ToFloat32(float128 a)
     249{
     250        float32 result;
     251        int32_t exp;
     252        uint64_t frac_hi, frac_lo;
     253
     254        result.parts.sign = a.parts.sign;
     255
     256        if (isFloat128NaN(a)) {
     257                result.parts.exp = FLOAT32_MAX_EXPONENT;
     258
     259                if (isFloat128SigNaN(a)) {
     260                        /* set first bit of fraction nonzero */
     261                        result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
     262                        return result;
     263                }
     264
     265                /* fraction nonzero but its first bit is zero */
     266                result.parts.fraction = 0x1;
     267                return result;
     268        }
     269
     270        if (isFloat128Infinity(a)) {
     271                result.parts.fraction = 0;
     272                result.parts.exp = FLOAT32_MAX_EXPONENT;
     273                return result;
     274        }
     275
     276        exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT32_BIAS;
     277
     278        if (exp >= FLOAT32_MAX_EXPONENT) {
     279                /* FIXME: overflow */
     280                result.parts.fraction = 0;
     281                result.parts.exp = FLOAT32_MAX_EXPONENT;
     282                return result;
     283        } else if (exp <= 0) {
     284                /* underflow or denormalized */
     285
     286                result.parts.exp = 0;
     287
     288                exp *= -1;
     289                if (exp > FLOAT32_FRACTION_SIZE) {
     290                        /* FIXME: underflow */
     291                        result.parts.fraction = 0;
     292                        return result;
     293                }
     294
     295                /* denormalized */
     296
     297                frac_hi = a.parts.frac_hi;
     298                frac_lo = a.parts.frac_lo;
     299
     300                /* denormalize and set hidden bit */
     301                frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
     302
     303                rshift128(frac_hi, frac_lo,
     304                    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
     305                    &frac_hi, &frac_lo);
     306
     307                while (exp > 0) {
     308                        --exp;
     309                        rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
     310                }
     311                result.parts.fraction = frac_lo;
     312
     313                return result;
     314        }
     315
     316        result.parts.exp = exp;
     317        frac_hi = a.parts.frac_hi;
     318        frac_lo = a.parts.frac_lo;
     319        rshift128(frac_hi, frac_lo,
     320            (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
     321            &frac_hi, &frac_lo);
     322        result.parts.fraction = frac_lo;
     323        return result;
     324}
     325
     326float64 convertFloat128ToFloat64(float128 a)
     327{
     328        float64 result;
     329        int32_t exp;
     330        uint64_t frac_hi, frac_lo;
     331
     332        result.parts.sign = a.parts.sign;
     333
     334        if (isFloat128NaN(a)) {
     335                result.parts.exp = FLOAT64_MAX_EXPONENT;
     336
     337                if (isFloat128SigNaN(a)) {
     338                        /* set first bit of fraction nonzero */
     339                        result.parts.fraction = FLOAT64_HIDDEN_BIT_MASK >> 1;
     340                        return result;
     341                }
     342
     343                /* fraction nonzero but its first bit is zero */
     344                result.parts.fraction = 0x1;
     345                return result;
     346        }
     347
     348        if (isFloat128Infinity(a)) {
     349                result.parts.fraction = 0;
     350                result.parts.exp = FLOAT64_MAX_EXPONENT;
     351                return result;
     352        }
     353
     354        exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT64_BIAS;
     355
     356        if (exp >= FLOAT64_MAX_EXPONENT) {
     357                /* FIXME: overflow */
     358                result.parts.fraction = 0;
     359                result.parts.exp = FLOAT64_MAX_EXPONENT;
     360                return result;
     361        } else if (exp <= 0) {
     362                /* underflow or denormalized */
     363
     364                result.parts.exp = 0;
     365
     366                exp *= -1;
     367                if (exp > FLOAT64_FRACTION_SIZE) {
     368                        /* FIXME: underflow */
     369                        result.parts.fraction = 0;
     370                        return result;
     371                }
     372
     373                /* denormalized */
     374
     375                frac_hi = a.parts.frac_hi;
     376                frac_lo = a.parts.frac_lo;
     377
     378                /* denormalize and set hidden bit */
     379                frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
     380
     381                rshift128(frac_hi, frac_lo,
     382                    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
     383                    &frac_hi, &frac_lo);
     384
     385                while (exp > 0) {
     386                        --exp;
     387                        rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
     388                }
     389                result.parts.fraction = frac_lo;
     390
     391                return result;
     392        }
     393
     394        result.parts.exp = exp;
     395        frac_hi = a.parts.frac_hi;
     396        frac_lo = a.parts.frac_lo;
     397        rshift128(frac_hi, frac_lo,
     398            (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
     399            &frac_hi, &frac_lo);
     400        result.parts.fraction = frac_lo;
     401        return result;
     402}
     403
     404
     405/**
     406 * Helping procedure for converting float32 to uint32.
     407 *
     408 * @param a Floating point number in normalized form
     409 *     (NaNs or Inf are not checked).
     410 * @return Converted unsigned integer.
    152411 */
    153412static uint32_t _float32_to_uint32_helper(float32 a)
     
    156415       
    157416        if (a.parts.exp < FLOAT32_BIAS) {
    158                 /*TODO: rounding*/
     417                /* TODO: rounding */
    159418                return 0;
    160419        }
     
    175434}
    176435
    177 /* Convert float to unsigned int32
     436/*
    178437 * FIXME: Im not sure what to return if overflow/underflow happens
    179438 *      - now its the biggest or the smallest int
     
    194453}
    195454
    196 /* Convert float to signed int32
     455/*
    197456 * FIXME: Im not sure what to return if overflow/underflow happens
    198457 *      - now its the biggest or the smallest int
     
    214473
    215474
    216 /** Helping procedure for converting float64 to uint64
    217  * @param a floating point number in normalized form (no NaNs or Inf are checked )
    218  * @return unsigned integer
     475/**
     476 * Helping procedure for converting float32 to uint64.
     477 *
     478 * @param a Floating point number in normalized form
     479 *     (NaNs or Inf are not checked).
     480 * @return Converted unsigned integer.
     481 */
     482static uint64_t _float32_to_uint64_helper(float32 a)
     483{
     484        uint64_t frac;
     485
     486        if (a.parts.exp < FLOAT32_BIAS) {
     487                /*TODO: rounding*/
     488                return 0;
     489        }
     490
     491        frac = a.parts.fraction;
     492
     493        frac |= FLOAT32_HIDDEN_BIT_MASK;
     494        /* shift fraction to left so hidden bit will be the most significant bit */
     495        frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
     496
     497        frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
     498        if ((a.parts.sign == 1) && (frac != 0)) {
     499                frac = ~frac;
     500                ++frac;
     501        }
     502
     503        return frac;
     504}
     505
     506/*
     507 * FIXME: Im not sure what to return if overflow/underflow happens
     508 *      - now its the biggest or the smallest int
     509 */
     510uint64_t float32_to_uint64(float32 a)
     511{
     512        if (isFloat32NaN(a))
     513                return UINT64_MAX;
     514
     515
     516        if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
     517                if (a.parts.sign)
     518                        return UINT64_MIN;
     519
     520                return UINT64_MAX;
     521        }
     522
     523        return _float32_to_uint64_helper(a);
     524}
     525
     526/*
     527 * FIXME: Im not sure what to return if overflow/underflow happens
     528 *      - now its the biggest or the smallest int
     529 */
     530int64_t float32_to_int64(float32 a)
     531{
     532        if (isFloat32NaN(a))
     533                return INT64_MAX;
     534
     535        if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
     536                if (a.parts.sign)
     537                        return INT64_MIN;
     538
     539                return INT64_MAX;
     540        }
     541
     542        return _float32_to_uint64_helper(a);
     543}
     544
     545
     546/**
     547 * Helping procedure for converting float64 to uint64.
     548 *
     549 * @param a Floating point number in normalized form
     550 *     (NaNs or Inf are not checked).
     551 * @return Converted unsigned integer.
    219552 */
    220553static uint64_t _float64_to_uint64_helper(float64 a)
    221554{
    222555        uint64_t frac;
    223        
     556
    224557        if (a.parts.exp < FLOAT64_BIAS) {
    225558                /*TODO: rounding*/
    226559                return 0;
    227560        }
    228        
     561
    229562        frac = a.parts.fraction;
    230        
     563
    231564        frac |= FLOAT64_HIDDEN_BIT_MASK;
    232565        /* shift fraction to left so hidden bit will be the most significant bit */
    233         frac <<= 64 - FLOAT64_FRACTION_SIZE - 1; 
     566        frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
    234567
    235568        frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
     
    238571                ++frac;
    239572        }
    240        
     573
    241574        return frac;
    242575}
    243576
    244 /* Convert float to unsigned int64
     577/*
     578 * FIXME: Im not sure what to return if overflow/underflow happens
     579 *      - now its the biggest or the smallest int
     580 */
     581uint32_t float64_to_uint32(float64 a)
     582{
     583        if (isFloat64NaN(a))
     584                return UINT32_MAX;
     585
     586        if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
     587                if (a.parts.sign)
     588                        return UINT32_MIN;
     589
     590                return UINT32_MAX;
     591        }
     592
     593        return (uint32_t) _float64_to_uint64_helper(a);
     594}
     595
     596/*
     597 * FIXME: Im not sure what to return if overflow/underflow happens
     598 *      - now its the biggest or the smallest int
     599 */
     600int32_t float64_to_int32(float64 a)
     601{
     602        if (isFloat64NaN(a))
     603                return INT32_MAX;
     604
     605        if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
     606                if (a.parts.sign)
     607                        return INT32_MIN;
     608
     609                return INT32_MAX;
     610        }
     611
     612        return (int32_t) _float64_to_uint64_helper(a);
     613}
     614
     615
     616/*
    245617 * FIXME: Im not sure what to return if overflow/underflow happens
    246618 *      - now its the biggest or the smallest int
     
    251623                return UINT64_MAX;
    252624       
    253        
    254625        if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
    255626                if (a.parts.sign)
     
    262633}
    263634
    264 /* Convert float to signed int64
     635/*
    265636 * FIXME: Im not sure what to return if overflow/underflow happens
    266637 *      - now its the biggest or the smallest int
     
    271642                return INT64_MAX;
    272643       
    273        
    274644        if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
    275645                if (a.parts.sign)
     
    283653
    284654
    285 
    286 
    287 
    288 /** Helping procedure for converting float32 to uint64
    289  * @param a floating point number in normalized form (no NaNs or Inf are checked )
    290  * @return unsigned integer
    291  */
    292 static uint64_t _float32_to_uint64_helper(float32 a)
    293 {
    294         uint64_t frac;
    295        
    296         if (a.parts.exp < FLOAT32_BIAS) {
     655/**
     656 * Helping procedure for converting float128 to uint64.
     657 *
     658 * @param a Floating point number in normalized form
     659 *     (NaNs or Inf are not checked).
     660 * @return Converted unsigned integer.
     661 */
     662static uint64_t _float128_to_uint64_helper(float128 a)
     663{
     664        uint64_t frac_hi, frac_lo;
     665
     666        if (a.parts.exp < FLOAT128_BIAS) {
    297667                /*TODO: rounding*/
    298668                return 0;
    299669        }
    300        
    301         frac = a.parts.fraction;
    302        
    303         frac |= FLOAT32_HIDDEN_BIT_MASK;
     670
     671        frac_hi = a.parts.frac_hi;
     672        frac_lo = a.parts.frac_lo;
     673
     674        frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
    304675        /* shift fraction to left so hidden bit will be the most significant bit */
    305         frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
    306 
    307         frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
    308         if ((a.parts.sign == 1) && (frac != 0)) {
    309                 frac = ~frac;
    310                 ++frac;
    311         }
    312        
    313         return frac;
    314 }
    315 
    316 /* Convert float to unsigned int64
    317  * FIXME: Im not sure what to return if overflow/underflow happens
    318  *      - now its the biggest or the smallest int
    319  */
    320 uint64_t float32_to_uint64(float32 a)
    321 {
    322         if (isFloat32NaN(a))
     676        lshift128(frac_hi, frac_lo,
     677            (128 - FLOAT128_FRACTION_SIZE - 1), &frac_hi, &frac_lo);
     678
     679        rshift128(frac_hi, frac_lo,
     680            (128 - (a.parts.exp - FLOAT128_BIAS) - 1), &frac_hi, &frac_lo);
     681        if ((a.parts.sign == 1) && !eq128(frac_hi, frac_lo, 0x0ll, 0x0ll)) {
     682                not128(frac_hi, frac_lo, &frac_hi, &frac_lo);
     683                add128(frac_hi, frac_lo, 0x0ll, 0x1ll, &frac_hi, &frac_lo);
     684        }
     685
     686        return frac_lo;
     687}
     688
     689/*
     690 * FIXME: Im not sure what to return if overflow/underflow happens
     691 *      - now its the biggest or the smallest int
     692 */
     693uint32_t float128_to_uint32(float128 a)
     694{
     695        if (isFloat128NaN(a))
     696                return UINT32_MAX;
     697
     698        if (isFloat128Infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
     699                if (a.parts.sign)
     700                        return UINT32_MIN;
     701
     702                return UINT32_MAX;
     703        }
     704
     705        return (uint32_t) _float128_to_uint64_helper(a);
     706}
     707
     708/*
     709 * FIXME: Im not sure what to return if overflow/underflow happens
     710 *      - now its the biggest or the smallest int
     711 */
     712int32_t float128_to_int32(float128 a)
     713{
     714        if (isFloat128NaN(a))
     715                return INT32_MAX;
     716
     717        if (isFloat128Infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
     718                if (a.parts.sign)
     719                        return INT32_MIN;
     720
     721                return INT32_MAX;
     722        }
     723
     724        return (int32_t) _float128_to_uint64_helper(a);
     725}
     726
     727
     728/*
     729 * FIXME: Im not sure what to return if overflow/underflow happens
     730 *      - now its the biggest or the smallest int
     731 */
     732uint64_t float128_to_uint64(float128 a)
     733{
     734        if (isFloat128NaN(a))
    323735                return UINT64_MAX;
    324        
    325        
    326         if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
     736
     737        if (isFloat128Infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
    327738                if (a.parts.sign)
    328739                        return UINT64_MIN;
    329                
     740
    330741                return UINT64_MAX;
    331742        }
    332        
    333         return _float32_to_uint64_helper(a);
    334 }
    335 
    336 /* Convert float to signed int64
    337  * FIXME: Im not sure what to return if overflow/underflow happens 
    338  *      - now its the biggest or the smallest int
    339  */ 
    340 int64_t float32_to_int64(float32 a)
    341 {
    342         if (isFloat32NaN(a))
     743
     744        return _float128_to_uint64_helper(a);
     745}
     746
     747/*
     748 * FIXME: Im not sure what to return if overflow/underflow happens
     749 *      - now its the biggest or the smallest int
     750 */
     751int64_t float128_to_int64(float128 a)
     752{
     753        if (isFloat128NaN(a))
    343754                return INT64_MAX;
    344        
    345         if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
     755
     756        if (isFloat128Infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
    346757                if (a.parts.sign)
    347758                        return INT64_MIN;
    348                
     759
    349760                return INT64_MAX;
    350761        }
    351        
    352         return _float32_to_uint64_helper(a);
    353 }
    354 
    355 
    356 /* Convert float64 to unsigned int32
    357  * FIXME: Im not sure what to return if overflow/underflow happens
    358  *      - now its the biggest or the smallest int
    359  */
    360 uint32_t float64_to_uint32(float64 a)
    361 {
    362         if (isFloat64NaN(a))
    363                 return UINT32_MAX;
    364        
    365        
    366         if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
    367                 if (a.parts.sign)
    368                         return UINT32_MIN;
    369                
    370                 return UINT32_MAX;
    371         }
    372        
    373         return (uint32_t) _float64_to_uint64_helper(a);
    374 }
    375 
    376 /* Convert float64 to signed int32
    377  * FIXME: Im not sure what to return if overflow/underflow happens
    378  *      - now its the biggest or the smallest int
    379  */
    380 int32_t float64_to_int32(float64 a)
    381 {
    382         if (isFloat64NaN(a))
    383                 return INT32_MAX;
    384        
    385        
    386         if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
    387                 if (a.parts.sign)
    388                         return INT32_MIN;
    389                
    390                 return INT32_MAX;
    391         }
    392        
    393         return (int32_t) _float64_to_uint64_helper(a);
    394 }
    395 
    396 /** Convert unsigned integer to float32
    397  *
    398  *
    399  */
     762
     763        return _float128_to_uint64_helper(a);
     764}
     765
     766
    400767float32 uint32_to_float32(uint32_t i)
    401768{
     
    424791        roundFloat32(&exp, &i);
    425792
    426         result.parts.fraction = i >> 7;
     793        result.parts.fraction = i >> (32 - FLOAT32_FRACTION_SIZE - 2);
    427794        result.parts.exp = exp;
    428795
     
    435802
    436803        if (i < 0) {
    437                 result = uint32_to_float32((uint32_t)(-i));
     804                result = uint32_to_float32((uint32_t) (-i));
    438805        } else {
    439                 result = uint32_to_float32((uint32_t)i);
     806                result = uint32_to_float32((uint32_t) i);
    440807        }
    441808       
     
    465832        }
    466833       
    467         /* Shift all to the first 31 bits (31. will be hidden 1)*/
     834        /* Shift all to the first 31 bits (31st will be hidden 1) */
    468835        if (counter > 33) {
    469836                i <<= counter - 1 - 32;
     
    472839        }
    473840       
    474         j = (uint32_t)i;
     841        j = (uint32_t) i;
    475842        roundFloat32(&exp, &j);
    476843
    477         result.parts.fraction = j >> 7;
     844        result.parts.fraction = j >> (32 - FLOAT32_FRACTION_SIZE - 2);
    478845        result.parts.exp = exp;
    479846        return result;
     
    485852
    486853        if (i < 0) {
    487                 result = uint64_to_float32((uint64_t)(-i));
     854                result = uint64_to_float32((uint64_t) (-i));
    488855        } else {
    489                 result = uint64_to_float32((uint64_t)i);
     856                result = uint64_to_float32((uint64_t) i);
    490857        }
    491858       
     
    495862}
    496863
    497 /** Convert unsigned integer to float64
    498  *
    499  *
    500  */
    501864float64 uint32_to_float64(uint32_t i)
    502865{
     
    523886        roundFloat64(&exp, &frac);
    524887
    525         result.parts.fraction = frac >> 10;
     888        result.parts.fraction = frac >> (64 - FLOAT64_FRACTION_SIZE - 2);
    526889        result.parts.exp = exp;
    527890
     
    534897
    535898        if (i < 0) {
    536                 result = uint32_to_float64((uint32_t)(-i));
     899                result = uint32_to_float64((uint32_t) (-i));
    537900        } else {
    538                 result = uint32_to_float64((uint32_t)i);
     901                result = uint32_to_float64((uint32_t) i);
    539902        }
    540903       
     
    571934        roundFloat64(&exp, &i);
    572935
    573         result.parts.fraction = i >> 10;
     936        result.parts.fraction = i >> (64 - FLOAT64_FRACTION_SIZE - 2);
    574937        result.parts.exp = exp;
    575938        return result;
     
    581944
    582945        if (i < 0) {
    583                 result = uint64_to_float64((uint64_t)(-i));
     946                result = uint64_to_float64((uint64_t) (-i));
    584947        } else {
    585                 result = uint64_to_float64((uint64_t)i);
     948                result = uint64_to_float64((uint64_t) i);
    586949        }
    587950       
     
    591954}
    592955
     956
     957float128 uint32_to_float128(uint32_t i)
     958{
     959        int counter;
     960        int32_t exp;
     961        float128 result;
     962        uint64_t frac_hi, frac_lo;
     963
     964        result.parts.sign = 0;
     965        result.parts.frac_hi = 0;
     966        result.parts.frac_lo = 0;
     967
     968        counter = countZeroes32(i);
     969
     970        exp = FLOAT128_BIAS + 32 - counter - 1;
     971
     972        if (counter == 32) {
     973                result.binary.hi = 0;
     974                result.binary.lo = 0;
     975                return result;
     976        }
     977
     978        frac_hi = 0;
     979        frac_lo = i;
     980        lshift128(frac_hi, frac_lo, (counter + 96 - 1), &frac_hi, &frac_lo);
     981
     982        roundFloat128(&exp, &frac_hi, &frac_lo);
     983
     984        rshift128(frac_hi, frac_lo,
     985            (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
     986        result.parts.frac_hi = frac_hi;
     987        result.parts.frac_lo = frac_lo;
     988        result.parts.exp = exp;
     989
     990        return result;
     991}
     992
     993float128 int32_to_float128(int32_t i)
     994{
     995        float128 result;
     996
     997        if (i < 0) {
     998                result = uint32_to_float128((uint32_t) (-i));
     999        } else {
     1000                result = uint32_to_float128((uint32_t) i);
     1001        }
     1002
     1003        result.parts.sign = i < 0;
     1004
     1005        return result;
     1006}
     1007
     1008
     1009float128 uint64_to_float128(uint64_t i)
     1010{
     1011        int counter;
     1012        int32_t exp;
     1013        float128 result;
     1014        uint64_t frac_hi, frac_lo;
     1015
     1016        result.parts.sign = 0;
     1017        result.parts.frac_hi = 0;
     1018        result.parts.frac_lo = 0;
     1019
     1020        counter = countZeroes64(i);
     1021
     1022        exp = FLOAT128_BIAS + 64 - counter - 1;
     1023
     1024        if (counter == 64) {
     1025                result.binary.hi = 0;
     1026                result.binary.lo = 0;
     1027                return result;
     1028        }
     1029
     1030        frac_hi = 0;
     1031        frac_lo = i;
     1032        lshift128(frac_hi, frac_lo, (counter + 64 - 1), &frac_hi, &frac_lo);
     1033
     1034        roundFloat128(&exp, &frac_hi, &frac_lo);
     1035
     1036        rshift128(frac_hi, frac_lo,
     1037            (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
     1038        result.parts.frac_hi = frac_hi;
     1039        result.parts.frac_lo = frac_lo;
     1040        result.parts.exp = exp;
     1041
     1042        return result;
     1043}
     1044
     1045float128 int64_to_float128(int64_t i)
     1046{
     1047        float128 result;
     1048
     1049        if (i < 0) {
     1050                result = uint64_to_float128((uint64_t) (-i));
     1051        } else {
     1052                result = uint64_to_float128((uint64_t) i);
     1053        }
     1054
     1055        result.parts.sign = i < 0;
     1056
     1057        return result;
     1058}
     1059
    5931060/** @}
    5941061 */
Note: See TracChangeset for help on using the changeset viewer.