Home | History | Annotate | Download | only in libyasm
      1 /*
      2  * Floating point number functions.
      3  *
      4  *  Copyright (C) 2001-2007  Peter Johnson
      5  *
      6  *  Based on public-domain x86 assembly code by Randall Hyde (8/28/91).
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 #include "util.h"
     30 
     31 #include <ctype.h>
     32 
     33 #include "coretype.h"
     34 #include "bitvect.h"
     35 #include "file.h"
     36 
     37 #include "errwarn.h"
     38 #include "floatnum.h"
     39 
     40 
     41 /* 97-bit internal floating point format:
     42  * 0000000s eeeeeeee eeeeeeee m.....................................m
     43  * Sign          exponent     mantissa (80 bits)
     44  *                            79                                    0
     45  *
     46  * Only L.O. bit of Sign byte is significant.  The rest is zero.
     47  * Exponent is bias 32767.
     48  * Mantissa does NOT have an implied one bit (it's explicit).
     49  */
     50 struct yasm_floatnum {
     51     /*@only@*/ wordptr mantissa;        /* Allocated to MANT_BITS bits */
     52     unsigned short exponent;
     53     unsigned char sign;
     54     unsigned char flags;
     55 };
     56 
     57 /* constants describing parameters of internal floating point format */
     58 #define MANT_BITS       80
     59 #define MANT_BYTES      10
     60 #define MANT_SIGDIGITS  24
     61 #define EXP_BIAS        0x7FFF
     62 #define EXP_INF         0xFFFF
     63 #define EXP_MAX         0xFFFE
     64 #define EXP_MIN         1
     65 #define EXP_ZERO        0
     66 
     67 /* Flag settings for flags field */
     68 #define FLAG_ISZERO     1<<0
     69 
     70 /* Note this structure integrates the floatnum structure */
     71 typedef struct POT_Entry_s {
     72     yasm_floatnum f;
     73     int dec_exponent;
     74 } POT_Entry;
     75 
     76 /* "Source" for POT_Entry. */
     77 typedef struct POT_Entry_Source_s {
     78     unsigned char mantissa[MANT_BYTES];     /* little endian mantissa */
     79     unsigned short exponent;                /* Bias 32767 exponent */
     80 } POT_Entry_Source;
     81 
     82 /* Power of ten tables used by the floating point I/O routines.
     83  * The POT_Table? arrays are built from the POT_Table?_Source arrays at
     84  * runtime by POT_Table_Init().
     85  */
     86 
     87 /* This table contains the powers of ten raised to negative powers of two:
     88  *
     89  * entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12.
     90  * entry[13] = 1.0
     91  */
     92 static /*@only@*/ POT_Entry *POT_TableN;
     93 static POT_Entry_Source POT_TableN_Source[] = {
     94     {{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */
     95     {{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */
     96     {{0xa6,0x87,0xbd,0xc0,0x57,0xda,0xa5,0x82,0xa6,0xa2},0x72b5}, /* 1e-1024 */
     97     {{0x33,0x71,0x1c,0xd2,0x23,0xdb,0x32,0xee,0x49,0x90},0x795a}, /* 1e-512 */
     98     {{0x91,0xfa,0x39,0x19,0x7a,0x63,0x25,0x43,0x31,0xc0},0x7cac}, /* 1e-256 */
     99     {{0x7d,0xac,0xa0,0xe4,0xbc,0x64,0x7c,0x46,0xd0,0xdd},0x7e55}, /* 1e-128 */
    100     {{0x24,0x3f,0xa5,0xe9,0x39,0xa5,0x27,0xea,0x7f,0xa8},0x7f2a}, /* 1e-64 */
    101     {{0xde,0x67,0xba,0x94,0x39,0x45,0xad,0x1e,0xb1,0xcf},0x7f94}, /* 1e-32 */
    102     {{0x2f,0x4c,0x5b,0xe1,0x4d,0xc4,0xbe,0x94,0x95,0xe6},0x7fc9}, /* 1e-16 */
    103     {{0xc2,0xfd,0xfc,0xce,0x61,0x84,0x11,0x77,0xcc,0xab},0x7fe4}, /* 1e-8 */
    104     {{0xc3,0xd3,0x2b,0x65,0x19,0xe2,0x58,0x17,0xb7,0xd1},0x7ff1}, /* 1e-4 */
    105     {{0x71,0x3d,0x0a,0xd7,0xa3,0x70,0x3d,0x0a,0xd7,0xa3},0x7ff8}, /* 1e-2 */
    106     {{0xcd,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc},0x7ffb}, /* 1e-1 */
    107     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e-0 */
    108 };
    109 
    110 /* This table contains the powers of ten raised to positive powers of two:
    111  *
    112  * entry[12-n] = 10 ** (2 ** n) for 0 <= n <= 12.
    113  * entry[13] = 1.0
    114  * entry[-1] = entry[0];
    115  *
    116  * There is a -1 entry since it is possible for the algorithm to back up
    117  * before the table.  This -1 entry is created at runtime by duplicating the
    118  * 0 entry.
    119  */
    120 static /*@only@*/ POT_Entry *POT_TableP;
    121 static POT_Entry_Source POT_TableP_Source[] = {
    122     {{0x4c,0xc9,0x9a,0x97,0x20,0x8a,0x02,0x52,0x60,0xc4},0xb525}, /* 1e+4096 */
    123     {{0x4d,0xa7,0xe4,0x5d,0x3d,0xc5,0x5d,0x3b,0x8b,0x9e},0x9a92}, /* 1e+2048 */
    124     {{0x0d,0x65,0x17,0x0c,0x75,0x81,0x86,0x75,0x76,0xc9},0x8d48}, /* 1e+1024 */
    125     {{0x65,0xcc,0xc6,0x91,0x0e,0xa6,0xae,0xa0,0x19,0xe3},0x86a3}, /* 1e+512 */
    126     {{0xbc,0xdd,0x8d,0xde,0xf9,0x9d,0xfb,0xeb,0x7e,0xaa},0x8351}, /* 1e+256 */
    127     {{0x6f,0xc6,0xdf,0x8c,0xe9,0x80,0xc9,0x47,0xba,0x93},0x81a8}, /* 1e+128 */
    128     {{0xbf,0x3c,0xd5,0xa6,0xcf,0xff,0x49,0x1f,0x78,0xc2},0x80d3}, /* 1e+64 */
    129     {{0x20,0xf0,0x9d,0xb5,0x70,0x2b,0xa8,0xad,0xc5,0x9d},0x8069}, /* 1e+32 */
    130     {{0x00,0x00,0x00,0x00,0x00,0x04,0xbf,0xc9,0x1b,0x8e},0x8034}, /* 1e+16 */
    131     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xbc,0xbe},0x8019}, /* 1e+8 */
    132     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9c},0x800c}, /* 1e+4 */
    133     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc8},0x8005}, /* 1e+2 */
    134     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0},0x8002}, /* 1e+1 */
    135     {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e+0 */
    136 };
    137 
    138 
    139 static void
    140 POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
    141 {
    142     /* Save decimal exponent */
    143     e->dec_exponent = dec_exp;
    144 
    145     /* Initialize mantissa */
    146     e->f.mantissa = BitVector_Create(MANT_BITS, FALSE);
    147     BitVector_Block_Store(e->f.mantissa, s->mantissa, MANT_BYTES);
    148 
    149     /* Initialize exponent */
    150     e->f.exponent = s->exponent;
    151 
    152     /* Set sign to 0 (positive) */
    153     e->f.sign = 0;
    154 
    155     /* Clear flags */
    156     e->f.flags = 0;
    157 }
    158 
    159 /*@-compdef@*/
    160 void
    161 yasm_floatnum_initialize(void)
    162 /*@globals undef POT_TableN, undef POT_TableP, POT_TableP_Source,
    163    POT_TableN_Source @*/
    164 {
    165     int dec_exp = 1;
    166     int i;
    167 
    168     /* Allocate space for two POT tables */
    169     POT_TableN = yasm_xmalloc(14*sizeof(POT_Entry));
    170     POT_TableP = yasm_xmalloc(15*sizeof(POT_Entry)); /* note 1 extra for -1 */
    171 
    172     /* Initialize entry[0..12] */
    173     for (i=12; i>=0; i--) {
    174         POT_Table_Init_Entry(&POT_TableN[i], &POT_TableN_Source[i], 0-dec_exp);
    175         POT_Table_Init_Entry(&POT_TableP[i+1], &POT_TableP_Source[i], dec_exp);
    176         dec_exp *= 2;       /* Update decimal exponent */
    177     }
    178 
    179     /* Initialize entry[13] */
    180     POT_Table_Init_Entry(&POT_TableN[13], &POT_TableN_Source[13], 0);
    181     POT_Table_Init_Entry(&POT_TableP[14], &POT_TableP_Source[13], 0);
    182 
    183     /* Initialize entry[-1] for POT_TableP */
    184     POT_Table_Init_Entry(&POT_TableP[0], &POT_TableP_Source[0], 4096);
    185 
    186     /* Offset POT_TableP so that [0] becomes [-1] */
    187     POT_TableP++;
    188 }
    189 /*@=compdef@*/
    190 
    191 /*@-globstate@*/
    192 void
    193 yasm_floatnum_cleanup(void)
    194 {
    195     int i;
    196 
    197     /* Un-offset POT_TableP */
    198     POT_TableP--;
    199 
    200     for (i=0; i<14; i++) {
    201         BitVector_Destroy(POT_TableN[i].f.mantissa);
    202         BitVector_Destroy(POT_TableP[i].f.mantissa);
    203     }
    204     BitVector_Destroy(POT_TableP[14].f.mantissa);
    205 
    206     yasm_xfree(POT_TableN);
    207     yasm_xfree(POT_TableP);
    208 }
    209 /*@=globstate@*/
    210 
    211 static void
    212 floatnum_normalize(yasm_floatnum *flt)
    213 {
    214     long norm_amt;
    215 
    216     if (BitVector_is_empty(flt->mantissa)) {
    217         flt->exponent = 0;
    218         return;
    219     }
    220 
    221     /* Look for the highest set bit, shift to make it the MSB, and adjust
    222      * exponent.  Don't let exponent go negative. */
    223     norm_amt = (MANT_BITS-1)-Set_Max(flt->mantissa);
    224     if (norm_amt > (long)flt->exponent)
    225         norm_amt = (long)flt->exponent;
    226     BitVector_Move_Left(flt->mantissa, (N_int)norm_amt);
    227     flt->exponent -= (unsigned short)norm_amt;
    228 }
    229 
    230 /* acc *= op */
    231 static void
    232 floatnum_mul(yasm_floatnum *acc, const yasm_floatnum *op)
    233 {
    234     long expon;
    235     wordptr product, op1, op2;
    236     long norm_amt;
    237 
    238     /* Compute the new sign */
    239     acc->sign ^= op->sign;
    240 
    241     /* Check for multiply by 0 */
    242     if (BitVector_is_empty(acc->mantissa) || BitVector_is_empty(op->mantissa)) {
    243         BitVector_Empty(acc->mantissa);
    244         acc->exponent = EXP_ZERO;
    245         return;
    246     }
    247 
    248     /* Add exponents, checking for overflow/underflow. */
    249     expon = (((int)acc->exponent)-EXP_BIAS) + (((int)op->exponent)-EXP_BIAS);
    250     expon += EXP_BIAS;
    251     if (expon > EXP_MAX) {
    252         /* Overflow; return infinity. */
    253         BitVector_Empty(acc->mantissa);
    254         acc->exponent = EXP_INF;
    255         return;
    256     } else if (expon < EXP_MIN) {
    257         /* Underflow; return zero. */
    258         BitVector_Empty(acc->mantissa);
    259         acc->exponent = EXP_ZERO;
    260         return;
    261     }
    262 
    263     /* Add one to the final exponent, as the multiply shifts one extra time. */
    264     acc->exponent = (unsigned short)(expon+1);
    265 
    266     /* Allocate space for the multiply result */
    267     product = BitVector_Create((N_int)((MANT_BITS+1)*2), FALSE);
    268 
    269     /* Allocate 1-bit-longer fields to force the operands to be unsigned */
    270     op1 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
    271     op2 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
    272 
    273     /* Make the operands unsigned after copying from original operands */
    274     BitVector_Copy(op1, acc->mantissa);
    275     BitVector_MSB(op1, 0);
    276     BitVector_Copy(op2, op->mantissa);
    277     BitVector_MSB(op2, 0);
    278 
    279     /* Compute the product of the mantissas */
    280     BitVector_Multiply(product, op1, op2);
    281 
    282     /* Normalize the product.  Note: we know the product is non-zero because
    283      * both of the original operands were non-zero.
    284      *
    285      * Look for the highest set bit, shift to make it the MSB, and adjust
    286      * exponent.  Don't let exponent go negative.
    287      */
    288     norm_amt = (MANT_BITS*2-1)-Set_Max(product);
    289     if (norm_amt > (long)acc->exponent)
    290         norm_amt = (long)acc->exponent;
    291     BitVector_Move_Left(product, (N_int)norm_amt);
    292     acc->exponent -= (unsigned short)norm_amt;
    293 
    294     /* Store the highest bits of the result */
    295     BitVector_Interval_Copy(acc->mantissa, product, 0, MANT_BITS, MANT_BITS);
    296 
    297     /* Free allocated variables */
    298     BitVector_Destroy(product);
    299     BitVector_Destroy(op1);
    300     BitVector_Destroy(op2);
    301 }
    302 
    303 yasm_floatnum *
    304 yasm_floatnum_create(const char *str)
    305 {
    306     yasm_floatnum *flt;
    307     int dec_exponent, dec_exp_add;      /* decimal (powers of 10) exponent */
    308     int POT_index;
    309     wordptr operand[2];
    310     int sig_digits;
    311     int decimal_pt;
    312     boolean carry;
    313 
    314     flt = yasm_xmalloc(sizeof(yasm_floatnum));
    315 
    316     flt->mantissa = BitVector_Create(MANT_BITS, TRUE);
    317 
    318     /* allocate and initialize calculation variables */
    319     operand[0] = BitVector_Create(MANT_BITS, TRUE);
    320     operand[1] = BitVector_Create(MANT_BITS, TRUE);
    321     dec_exponent = 0;
    322     sig_digits = 0;
    323     decimal_pt = 1;
    324 
    325     /* set initial flags to 0 */
    326     flt->flags = 0;
    327 
    328     /* check for + or - character and skip */
    329     if (*str == '-') {
    330         flt->sign = 1;
    331         str++;
    332     } else if (*str == '+') {
    333         flt->sign = 0;
    334         str++;
    335     } else
    336         flt->sign = 0;
    337 
    338     /* eliminate any leading zeros (which do not count as significant digits) */
    339     while (*str == '0')
    340         str++;
    341 
    342     /* When we reach the end of the leading zeros, first check for a decimal
    343      * point.  If the number is of the form "0---0.0000" we need to get rid
    344      * of the zeros after the decimal point and not count them as significant
    345      * digits.
    346      */
    347     if (*str == '.') {
    348         str++;
    349         while (*str == '0') {
    350             str++;
    351             dec_exponent--;
    352         }
    353     } else {
    354         /* The number is of the form "yyy.xxxx" (where y <> 0). */
    355         while (isdigit(*str)) {
    356             /* See if we've processed more than the max significant digits: */
    357             if (sig_digits < MANT_SIGDIGITS) {
    358                 /* Multiply mantissa by 10 [x = (x<<1)+(x<<3)] */
    359                 BitVector_shift_left(flt->mantissa, 0);
    360                 BitVector_Copy(operand[0], flt->mantissa);
    361                 BitVector_Move_Left(flt->mantissa, 2);
    362                 carry = 0;
    363                 BitVector_add(operand[1], operand[0], flt->mantissa, &carry);
    364 
    365                 /* Add in current digit */
    366                 BitVector_Empty(operand[0]);
    367                 BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
    368                 carry = 0;
    369                 BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
    370             } else {
    371                 /* Can't integrate more digits with mantissa, so instead just
    372                  * raise by a power of ten.
    373                  */
    374                 dec_exponent++;
    375             }
    376             sig_digits++;
    377             str++;
    378         }
    379 
    380         if (*str == '.')
    381             str++;
    382         else
    383             decimal_pt = 0;
    384     }
    385 
    386     if (decimal_pt) {
    387         /* Process the digits to the right of the decimal point. */
    388         while (isdigit(*str)) {
    389             /* See if we've processed more than 19 significant digits: */
    390             if (sig_digits < 19) {
    391                 /* Raise by a power of ten */
    392                 dec_exponent--;
    393 
    394                 /* Multiply mantissa by 10 [x = (x<<1)+(x<<3)] */
    395                 BitVector_shift_left(flt->mantissa, 0);
    396                 BitVector_Copy(operand[0], flt->mantissa);
    397                 BitVector_Move_Left(flt->mantissa, 2);
    398                 carry = 0;
    399                 BitVector_add(operand[1], operand[0], flt->mantissa, &carry);
    400 
    401                 /* Add in current digit */
    402                 BitVector_Empty(operand[0]);
    403                 BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
    404                 carry = 0;
    405                 BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
    406             }
    407             sig_digits++;
    408             str++;
    409         }
    410     }
    411 
    412     if (*str == 'e' || *str == 'E') {
    413         str++;
    414         /* We just saw the "E" character, now read in the exponent value and
    415          * add it into dec_exponent.
    416          */
    417         dec_exp_add = 0;
    418         sscanf(str, "%d", &dec_exp_add);
    419         dec_exponent += dec_exp_add;
    420     }
    421 
    422     /* Free calculation variables. */
    423     BitVector_Destroy(operand[1]);
    424     BitVector_Destroy(operand[0]);
    425 
    426     /* Normalize the number, checking for 0 first. */
    427     if (BitVector_is_empty(flt->mantissa)) {
    428         /* Mantissa is 0, zero exponent too. */
    429         flt->exponent = 0;
    430         /* Set zero flag so output functions don't see 0 value as underflow. */
    431         flt->flags |= FLAG_ISZERO;
    432         /* Return 0 value. */
    433         return flt;
    434     }
    435     /* Exponent if already norm. */
    436     flt->exponent = (unsigned short)(0x7FFF+(MANT_BITS-1));
    437     floatnum_normalize(flt);
    438 
    439     /* The number is normalized.  Now multiply by 10 the number of times
    440      * specified in DecExponent.  This uses the power of ten tables to speed
    441      * up this operation (and make it more accurate).
    442      */
    443     if (dec_exponent > 0) {
    444         POT_index = 0;
    445         /* Until we hit 1.0 or finish exponent or overflow */
    446         while ((POT_index < 14) && (dec_exponent != 0) &&
    447                (flt->exponent != EXP_INF)) {
    448             /* Find the first power of ten in the table which is just less than
    449              * the exponent.
    450              */
    451             while (dec_exponent < POT_TableP[POT_index].dec_exponent)
    452                 POT_index++;
    453 
    454             if (POT_index < 14) {
    455                 /* Subtract out what we're multiplying in from exponent */
    456                 dec_exponent -= POT_TableP[POT_index].dec_exponent;
    457 
    458                 /* Multiply by current power of 10 */
    459                 floatnum_mul(flt, &POT_TableP[POT_index].f);
    460             }
    461         }
    462     } else if (dec_exponent < 0) {
    463         POT_index = 0;
    464         /* Until we hit 1.0 or finish exponent or underflow */
    465         while ((POT_index < 14) && (dec_exponent != 0) &&
    466                (flt->exponent != EXP_ZERO)) {
    467             /* Find the first power of ten in the table which is just less than
    468              * the exponent.
    469              */
    470             while (dec_exponent > POT_TableN[POT_index].dec_exponent)
    471                 POT_index++;
    472 
    473             if (POT_index < 14) {
    474                 /* Subtract out what we're multiplying in from exponent */
    475                 dec_exponent -= POT_TableN[POT_index].dec_exponent;
    476 
    477                 /* Multiply by current power of 10 */
    478                 floatnum_mul(flt, &POT_TableN[POT_index].f);
    479             }
    480         }
    481     }
    482 
    483     /* Round the result. (Don't round underflow or overflow).  Also don't
    484      * increment if this would cause the mantissa to wrap.
    485      */
    486     if ((flt->exponent != EXP_INF) && (flt->exponent != EXP_ZERO) &&
    487         !BitVector_is_full(flt->mantissa))
    488         BitVector_increment(flt->mantissa);
    489 
    490     return flt;
    491 }
    492 
    493 yasm_floatnum *
    494 yasm_floatnum_copy(const yasm_floatnum *flt)
    495 {
    496     yasm_floatnum *f = yasm_xmalloc(sizeof(yasm_floatnum));
    497 
    498     f->mantissa = BitVector_Clone(flt->mantissa);
    499     f->exponent = flt->exponent;
    500     f->sign = flt->sign;
    501     f->flags = flt->flags;
    502 
    503     return f;
    504 }
    505 
    506 void
    507 yasm_floatnum_destroy(yasm_floatnum *flt)
    508 {
    509     BitVector_Destroy(flt->mantissa);
    510     yasm_xfree(flt);
    511 }
    512 
    513 int
    514 yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
    515                    /*@unused@*/ yasm_floatnum *operand)
    516 {
    517     if (op != YASM_EXPR_NEG) {
    518         yasm_error_set(YASM_ERROR_FLOATING_POINT,
    519                        N_("Unsupported floating-point arithmetic operation"));
    520         return 1;
    521     }
    522     acc->sign ^= 1;
    523     return 0;
    524 }
    525 
    526 int
    527 yasm_floatnum_get_int(const yasm_floatnum *flt, unsigned long *ret_val)
    528 {
    529     unsigned char t[4];
    530 
    531     if (yasm_floatnum_get_sized(flt, t, 4, 32, 0, 0, 0)) {
    532         *ret_val = 0xDEADBEEFUL;    /* Obviously incorrect return value */
    533         return 1;
    534     }
    535 
    536     YASM_LOAD_32_L(*ret_val, &t[0]);
    537     return 0;
    538 }
    539 
    540 /* Function used by conversion routines to actually perform the conversion.
    541  *
    542  * ptr -> the array to return the little-endian floating point value into.
    543  * flt -> the floating point value to convert.
    544  * byte_size -> the size in bytes of the output format.
    545  * mant_bits -> the size in bits of the output mantissa.
    546  * implicit1 -> does the output format have an implicit 1? 1=yes, 0=no.
    547  * exp_bits -> the size in bits of the output exponent.
    548  *
    549  * Returns 0 on success, 1 if overflow, -1 if underflow.
    550  */
    551 static int
    552 floatnum_get_common(const yasm_floatnum *flt, /*@out@*/ unsigned char *ptr,
    553                     N_int byte_size, N_int mant_bits, int implicit1,
    554                     N_int exp_bits)
    555 {
    556     long exponent = (long)flt->exponent;
    557     wordptr output;
    558     charptr buf;
    559     unsigned int len;
    560     unsigned int overflow = 0, underflow = 0;
    561     int retval = 0;
    562     long exp_bias = (1<<(exp_bits-1))-1;
    563     long exp_inf = (1<<exp_bits)-1;
    564 
    565     output = BitVector_Create(byte_size*8, TRUE);
    566 
    567     /* copy mantissa */
    568     BitVector_Interval_Copy(output, flt->mantissa, 0,
    569                             (N_int)((MANT_BITS-implicit1)-mant_bits),
    570                             mant_bits);
    571 
    572     /* round mantissa */
    573     if (BitVector_bit_test(flt->mantissa, (MANT_BITS-implicit1)-(mant_bits+1)))
    574         BitVector_increment(output);
    575 
    576     if (BitVector_bit_test(output, mant_bits)) {
    577         /* overflowed, so zero mantissa (and set explicit bit if necessary) */
    578         BitVector_Empty(output);
    579         BitVector_Bit_Copy(output, mant_bits-1, !implicit1);
    580         /* and up the exponent (checking for overflow) */
    581         if (exponent+1 >= EXP_INF)
    582             overflow = 1;
    583         else
    584             exponent++;
    585     }
    586 
    587     /* adjust the exponent to the output bias, checking for overflow */
    588     exponent -= EXP_BIAS-exp_bias;
    589     if (exponent >= exp_inf)
    590         overflow = 1;
    591     else if (exponent <= 0)
    592         underflow = 1;
    593 
    594     /* underflow and overflow both set!? */
    595     if (underflow && overflow)
    596         yasm_internal_error(N_("Both underflow and overflow set"));
    597 
    598     /* check for underflow or overflow and set up appropriate output */
    599     if (underflow) {
    600         BitVector_Empty(output);
    601         exponent = 0;
    602         if (!(flt->flags & FLAG_ISZERO))
    603             retval = -1;
    604     } else if (overflow) {
    605         BitVector_Empty(output);
    606         exponent = exp_inf;
    607         retval = 1;
    608     }
    609 
    610     /* move exponent into place */
    611     BitVector_Chunk_Store(output, exp_bits, mant_bits, (N_long)exponent);
    612 
    613     /* merge in sign bit */
    614     BitVector_Bit_Copy(output, byte_size*8-1, flt->sign);
    615 
    616     /* get little-endian bytes */
    617     buf = BitVector_Block_Read(output, &len);
    618     if (len < byte_size)
    619         yasm_internal_error(
    620             N_("Byte length of BitVector does not match bit length"));
    621 
    622     /* copy to output */
    623     memcpy(ptr, buf, byte_size*sizeof(unsigned char));
    624 
    625     /* free allocated resources */
    626     yasm_xfree(buf);
    627 
    628     BitVector_Destroy(output);
    629 
    630     return retval;
    631 }
    632 
    633 /* IEEE-754r "half precision" format:
    634  * 16 bits:
    635  * 15     9      Bit 0
    636  * |      |          |
    637  * seee eemm mmmm mmmm
    638  *
    639  * e = bias 15 exponent
    640  * s = sign bit
    641  * m = mantissa bits, bit 10 is an implied one bit.
    642  *
    643  * IEEE-754 (Intel) "single precision" format:
    644  * 32 bits:
    645  * Bit 31    Bit 22              Bit 0
    646  * |         |                       |
    647  * seeeeeee emmmmmmm mmmmmmmm mmmmmmmm
    648  *
    649  * e = bias 127 exponent
    650  * s = sign bit
    651  * m = mantissa bits, bit 23 is an implied one bit.
    652  *
    653  * IEEE-754 (Intel) "double precision" format:
    654  * 64 bits:
    655  * bit 63       bit 51                                               bit 0
    656  * |            |                                                        |
    657  * seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm
    658  *
    659  * e = bias 1023 exponent.
    660  * s = sign bit.
    661  * m = mantissa bits.  Bit 52 is an implied one bit.
    662  *
    663  * IEEE-754 (Intel) "extended precision" format:
    664  * 80 bits:
    665  * bit 79            bit 63                           bit 0
    666  * |                 |                                    |
    667  * seeeeeee eeeeeeee mmmmmmmm m...m m...m m...m m...m m...m
    668  *
    669  * e = bias 16383 exponent
    670  * m = 64 bit mantissa with NO implied bit!
    671  * s = sign (for mantissa)
    672  */
    673 int
    674 yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
    675                         size_t destsize, size_t valsize, size_t shift,
    676                         int bigendian, int warn)
    677 {
    678     int retval;
    679     if (destsize*8 != valsize || shift>0 || bigendian) {
    680         /* TODO */
    681         yasm_internal_error(N_("unsupported floatnum functionality"));
    682     }
    683     switch (destsize) {
    684         case 2:
    685             retval = floatnum_get_common(flt, ptr, 2, 10, 1, 5);
    686             break;
    687         case 4:
    688             retval = floatnum_get_common(flt, ptr, 4, 23, 1, 8);
    689             break;
    690         case 8:
    691             retval = floatnum_get_common(flt, ptr, 8, 52, 1, 11);
    692             break;
    693         case 10:
    694             retval = floatnum_get_common(flt, ptr, 10, 64, 0, 15);
    695             break;
    696         default:
    697             yasm_internal_error(N_("Invalid float conversion size"));
    698             /*@notreached@*/
    699             return 1;
    700     }
    701     if (warn) {
    702         if (retval < 0)
    703             yasm_warn_set(YASM_WARN_GENERAL,
    704                           N_("underflow in floating point expression"));
    705         else if (retval > 0)
    706             yasm_warn_set(YASM_WARN_GENERAL,
    707                           N_("overflow in floating point expression"));
    708     }
    709     return retval;
    710 }
    711 
    712 /* 1 if the size is valid, 0 if it isn't */
    713 int
    714 yasm_floatnum_check_size(/*@unused@*/ const yasm_floatnum *flt, size_t size)
    715 {
    716     switch (size) {
    717         case 16:
    718         case 32:
    719         case 64:
    720         case 80:
    721             return 1;
    722         default:
    723             return 0;
    724     }
    725 }
    726 
    727 void
    728 yasm_floatnum_print(const yasm_floatnum *flt, FILE *f)
    729 {
    730     unsigned char out[10];
    731     unsigned char *str;
    732     int i;
    733 
    734     /* Internal format */
    735     str = BitVector_to_Hex(flt->mantissa);
    736     fprintf(f, "%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str,
    737             flt->exponent);
    738     yasm_xfree(str);
    739 
    740     /* 32-bit (single precision) format */
    741     fprintf(f, "32-bit: %d: ",
    742             yasm_floatnum_get_sized(flt, out, 4, 32, 0, 0, 0));
    743     for (i=0; i<4; i++)
    744         fprintf(f, "%02x ", out[i]);
    745     fprintf(f, "\n");
    746 
    747     /* 64-bit (double precision) format */
    748     fprintf(f, "64-bit: %d: ",
    749             yasm_floatnum_get_sized(flt, out, 8, 64, 0, 0, 0));
    750     for (i=0; i<8; i++)
    751         fprintf(f, "%02x ", out[i]);
    752     fprintf(f, "\n");
    753 
    754     /* 80-bit (extended precision) format */
    755     fprintf(f, "80-bit: %d: ",
    756             yasm_floatnum_get_sized(flt, out, 10, 80, 0, 0, 0));
    757     for (i=0; i<10; i++)
    758         fprintf(f, "%02x ", out[i]);
    759     fprintf(f, "\n");
    760 }
    761