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