|
|
1.1 ! root 1: /* atof_ieee.c - turn a Flonum into an IEEE floating point number ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GAS, the GNU Assembler. ! 5: ! 6: GAS is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: ! 11: GAS is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GAS; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: #include <stdio.h> ! 21: #include <stdlib.h> ! 22: #include <string.h> ! 23: #include "expr.h" ! 24: #include "md.h" ! 25: #include "atof-ieee.h" ! 26: #include "messages.h" ! 27: ! 28: /* Precision in LittleNums. */ ! 29: #define MAX_PRECISION (6) ! 30: #define F_PRECISION (2) ! 31: #define D_PRECISION (4) ! 32: #define X_PRECISION (6) ! 33: #define P_PRECISION (6) ! 34: ! 35: /* Length in LittleNums of guard bits. */ ! 36: #define GUARD (2) ! 37: ! 38: static unsigned long int mask [] = { ! 39: 0x00000000, ! 40: 0x00000001, ! 41: 0x00000003, ! 42: 0x00000007, ! 43: 0x0000000f, ! 44: 0x0000001f, ! 45: 0x0000003f, ! 46: 0x0000007f, ! 47: 0x000000ff, ! 48: 0x000001ff, ! 49: 0x000003ff, ! 50: 0x000007ff, ! 51: 0x00000fff, ! 52: 0x00001fff, ! 53: 0x00003fff, ! 54: 0x00007fff, ! 55: 0x0000ffff, ! 56: 0x0001ffff, ! 57: 0x0003ffff, ! 58: 0x0007ffff, ! 59: 0x000fffff, ! 60: 0x001fffff, ! 61: 0x003fffff, ! 62: 0x007fffff, ! 63: 0x00ffffff, ! 64: 0x01ffffff, ! 65: 0x03ffffff, ! 66: 0x07ffffff, ! 67: 0x0fffffff, ! 68: 0x1fffffff, ! 69: 0x3fffffff, ! 70: 0x7fffffff, ! 71: 0xffffffff ! 72: }; ! 73: ! 74: static int bits_left_in_littlenum; ! 75: static int littlenums_left; ! 76: static LITTLENUM_TYPE *littlenum_pointer; ! 77: ! 78: static ! 79: int ! 80: next_bits( ! 81: int number_of_bits) ! 82: { ! 83: int return_value; ! 84: ! 85: if(!littlenums_left) ! 86: return 0; ! 87: if (number_of_bits >= bits_left_in_littlenum) ! 88: { ! 89: return_value = mask [bits_left_in_littlenum] & *littlenum_pointer; ! 90: number_of_bits -= bits_left_in_littlenum; ! 91: return_value <<= number_of_bits; ! 92: if(--littlenums_left) { ! 93: bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; ! 94: littlenum_pointer --; ! 95: return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits]; ! 96: } ! 97: } ! 98: else ! 99: { ! 100: bits_left_in_littlenum -= number_of_bits; ! 101: return_value = mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum); ! 102: } ! 103: return (return_value); ! 104: } ! 105: ! 106: /* Num had better be less than LITTLENUM_NUMBER_OF_BITS */ ! 107: static ! 108: void ! 109: unget_bits( ! 110: int num) ! 111: { ! 112: if(!littlenums_left) { ! 113: ++littlenum_pointer; ! 114: ++littlenums_left; ! 115: bits_left_in_littlenum=num; ! 116: } else if(bits_left_in_littlenum+num>LITTLENUM_NUMBER_OF_BITS) { ! 117: bits_left_in_littlenum= num-(LITTLENUM_NUMBER_OF_BITS-bits_left_in_littlenum); ! 118: ++littlenum_pointer; ! 119: ++littlenums_left; ! 120: } else ! 121: bits_left_in_littlenum+=num; ! 122: } ! 123: ! 124: static ! 125: void ! 126: make_invalid_floating_point_number( ! 127: LITTLENUM_TYPE *words) ! 128: { ! 129: as_warn("cannot create floating-point number"); ! 130: words[0]= (LITTLENUM_TYPE)(((unsigned)-1)>>1);/* Zero the leftmost bit*/ ! 131: words[1]= -1; ! 132: words[2]= -1; ! 133: words[3]= -1; ! 134: words[4]= -1; ! 135: words[5]= -1; ! 136: } ! 137: ! 138: /***********************************************************************\ ! 139: * Warning: this returns 16-bit LITTLENUMs. It is up to the caller * ! 140: * to figure out any alignment problems and to conspire for the * ! 141: * bytes/word to be emitted in the right order. Bigendians beware! * ! 142: * * ! 143: \***********************************************************************/ ! 144: ! 145: /* Note that atof-ieee always has X and P precisions enabled. it is up ! 146: to md_atof to filter them out if the target machine does not support ! 147: them. */ ! 148: ! 149: char * /* Return pointer past text consumed. */ ! 150: atof_ieee( ! 151: char *str, /* Text to convert to binary. */ ! 152: char what_kind, /* 'd', 'f', 'g', 'h' */ ! 153: LITTLENUM_TYPE *words) /* Build the binary here. */ ! 154: { ! 155: static LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; ! 156: /* Extra bits for zeroed low-order bits. */ ! 157: /* The 1st MAX_PRECISION are zeroed, */ ! 158: /* the last contain flonum bits. */ ! 159: char * return_value; ! 160: int precision; /* Number of 16-bit words in the format. */ ! 161: long int exponent_bits; ! 162: ! 163: return_value = str; ! 164: generic_floating_point_number.low = bits + MAX_PRECISION; ! 165: generic_floating_point_number.high = NULL; ! 166: generic_floating_point_number.leader = NULL; ! 167: generic_floating_point_number.exponent = 0; ! 168: generic_floating_point_number.sign = '\0'; ! 169: ! 170: /* Use more LittleNums than seems */ ! 171: /* necessary: the highest flonum may have */ ! 172: /* 15 leading 0 bits, so could be useless. */ ! 173: ! 174: memset(bits, '\0', sizeof(LITTLENUM_TYPE) * MAX_PRECISION); ! 175: ! 176: switch(what_kind) { ! 177: case 'f': ! 178: case 'F': ! 179: case 's': ! 180: case 'S': ! 181: precision = F_PRECISION; ! 182: exponent_bits = 8; ! 183: break; ! 184: ! 185: case 'd': ! 186: case 'D': ! 187: case 'r': ! 188: case 'R': ! 189: precision = D_PRECISION; ! 190: exponent_bits = 11; ! 191: break; ! 192: ! 193: case 'x': ! 194: case 'X': ! 195: case 'e': ! 196: case 'E': ! 197: precision = X_PRECISION; ! 198: exponent_bits = 15; ! 199: break; ! 200: ! 201: case 'p': ! 202: case 'P': ! 203: ! 204: precision = P_PRECISION; ! 205: exponent_bits= -1; ! 206: break; ! 207: ! 208: default: ! 209: make_invalid_floating_point_number (words); ! 210: return NULL; ! 211: } ! 212: ! 213: generic_floating_point_number.high = generic_floating_point_number.low + precision - 1 + GUARD; ! 214: ! 215: if (atof_generic (& return_value, ".", md_EXP_CHARS, & generic_floating_point_number)) { ! 216: /* as_warn("Error converting floating point number (Exponent overflow?)"); */ ! 217: #ifdef NeXT ! 218: if(precision==F_PRECISION) { ! 219: words[0]=0x7f80; ! 220: words[1]=0; ! 221: } else { ! 222: words[0]=0x7ff0; ! 223: words[1]=0; ! 224: words[2]=0; ! 225: words[3]=0; ! 226: } ! 227: if(generic_floating_point_number.sign=='-') ! 228: words[0] |= 0x8000; ! 229: return return_value; ! 230: #else /* NeXT */ ! 231: make_invalid_floating_point_number (words); ! 232: return NULL; ! 233: #endif /* NeXT */ ! 234: } ! 235: gen_to_words(words, precision, exponent_bits); ! 236: return return_value; ! 237: } ! 238: ! 239: /* Turn generic_floating_point_number into a real float/double/extended */ ! 240: int ! 241: gen_to_words( ! 242: LITTLENUM_TYPE *words, ! 243: int precision, ! 244: int exponent_bits) ! 245: { ! 246: int return_value=0; ! 247: ! 248: long int exponent_1; ! 249: long int exponent_2; ! 250: long int exponent_3; ! 251: long int exponent_4; ! 252: int exponent_skippage; ! 253: LITTLENUM_TYPE word1; ! 254: LITTLENUM_TYPE * lp; ! 255: ! 256: if (generic_floating_point_number.low > generic_floating_point_number.leader) { ! 257: /* 0.0e0 seen. */ ! 258: if(generic_floating_point_number.sign=='+') ! 259: words[0]=0x0000; ! 260: else ! 261: words[0]=0x8000; ! 262: memset(&words[1], '\0', sizeof(LITTLENUM_TYPE) * (precision-1)); ! 263: return return_value; ! 264: } ! 265: ! 266: /* NaN: Do the right thing */ ! 267: if(generic_floating_point_number.sign==0) { ! 268: if(precision==F_PRECISION) { ! 269: words[0]=0x7fff; ! 270: words[1]=0xffff; ! 271: } else { ! 272: words[0]=0x7fff; ! 273: words[1]=0xffff; ! 274: words[2]=0xffff; ! 275: words[3]=0xffff; ! 276: } ! 277: return return_value; ! 278: } else if(generic_floating_point_number.sign=='P') { ! 279: /* +INF: Do the right thing */ ! 280: if(precision==F_PRECISION) { ! 281: words[0]=0x7f80; ! 282: words[1]=0; ! 283: } else { ! 284: words[0]=0x7ff0; ! 285: words[1]=0; ! 286: words[2]=0; ! 287: words[3]=0; ! 288: } ! 289: return return_value; ! 290: } else if(generic_floating_point_number.sign=='N') { ! 291: /* Negative INF */ ! 292: if(precision==F_PRECISION) { ! 293: words[0]=0xff80; ! 294: words[1]=0x0; ! 295: } else { ! 296: words[0]=0xfff0; ! 297: words[1]=0x0; ! 298: words[2]=0x0; ! 299: words[3]=0x0; ! 300: } ! 301: return return_value; ! 302: } ! 303: /* ! 304: * The floating point formats we support have: ! 305: * Bit 15 is sign bit. ! 306: * Bits 14:n are excess-whatever exponent. ! 307: * Bits n-1:0 (if any) are most significant bits of fraction. ! 308: * Bits 15:0 of the next word(s) are the next most significant bits. ! 309: * ! 310: * So we need: number of bits of exponent, number of bits of ! 311: * mantissa. ! 312: */ ! 313: bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; ! 314: littlenum_pointer = generic_floating_point_number.leader; ! 315: littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low; ! 316: /* Seek (and forget) 1st significant bit */ ! 317: for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ! 318: ; ! 319: exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 - ! 320: generic_floating_point_number.low; ! 321: /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */ ! 322: exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; ! 323: /* Radix 2. */ ! 324: exponent_3 = exponent_2 - exponent_skippage; ! 325: /* Forget leading zeros, forget 1st bit. */ ! 326: exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); ! 327: /* Offset exponent. */ ! 328: ! 329: lp = words; ! 330: ! 331: /* Word 1. Sign, exponent and perhaps high bits. */ ! 332: word1 = (generic_floating_point_number.sign == '+') ? 0 : (1<<(LITTLENUM_NUMBER_OF_BITS-1)); ! 333: ! 334: /* Assume 2's complement integers. */ ! 335: if(exponent_4<1 && exponent_4>=-62) { ! 336: int prec_bits; ! 337: int num_bits; ! 338: ! 339: unget_bits(1); ! 340: num_bits= -exponent_4; ! 341: prec_bits=LITTLENUM_NUMBER_OF_BITS*precision-(exponent_bits+1+num_bits); ! 342: if(precision==X_PRECISION && exponent_bits==15) ! 343: prec_bits-=LITTLENUM_NUMBER_OF_BITS+1; ! 344: ! 345: if(num_bits>=LITTLENUM_NUMBER_OF_BITS-exponent_bits) { ! 346: /* Bigger than one littlenum */ ! 347: num_bits-=(LITTLENUM_NUMBER_OF_BITS-1)-exponent_bits; ! 348: *lp++=word1; ! 349: if(num_bits+exponent_bits+1>=precision*LITTLENUM_NUMBER_OF_BITS) { ! 350: /* Exponent overflow */ ! 351: #ifdef NeXT ! 352: if(precision==F_PRECISION) { ! 353: words[0]=0x7f80; ! 354: words[1]=0; ! 355: } else { ! 356: words[0]=0x7ff0; ! 357: words[1]=0; ! 358: words[2]=0; ! 359: words[3]=0; ! 360: } ! 361: if(generic_floating_point_number.sign=='-') ! 362: words[0] |= 0x8000; ! 363: return return_value; ! 364: #else /* NeXT */ ! 365: make_invalid_floating_point_number(words); ! 366: return return_value; ! 367: #endif /* NeXT */ ! 368: } ! 369: if(precision==X_PRECISION && exponent_bits==15) { ! 370: *lp++=0; ! 371: *lp++=0; ! 372: num_bits-=LITTLENUM_NUMBER_OF_BITS-1; ! 373: } ! 374: while(num_bits>=LITTLENUM_NUMBER_OF_BITS) { ! 375: num_bits-=LITTLENUM_NUMBER_OF_BITS; ! 376: *lp++=0; ! 377: } ! 378: if(num_bits) ! 379: *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-(num_bits)); ! 380: } else { ! 381: if(precision==X_PRECISION && exponent_bits==15) { ! 382: *lp++=word1; ! 383: *lp++=0; ! 384: if(num_bits==LITTLENUM_NUMBER_OF_BITS) { ! 385: *lp++=0; ! 386: *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1); ! 387: } else if(num_bits==LITTLENUM_NUMBER_OF_BITS-1) ! 388: *lp++=0; ! 389: else ! 390: *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1-num_bits); ! 391: num_bits=0; ! 392: } else { ! 393: word1|= next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - (exponent_bits+num_bits)); ! 394: *lp++=word1; ! 395: } ! 396: } ! 397: while(lp<words+precision) ! 398: *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS); ! 399: ! 400: #ifdef NeXT ! 401: /* ! 402: * Round the mantissa up, and let the rounding change the ! 403: * number if that happens. Noting that the largest denorm ! 404: * rounded up will produce the correct smallest normalilized ! 405: * number. This is not correct IEEE round to nearest as if ! 406: * the number is exactly half way between two numbers (the ! 407: * round bit is set and all lower bits are zero) the last bit ! 408: * is not set to zero. This would require that the input ! 409: * flonum be created from the decimal string with a correct ! 410: * sticky bit for the remaining digits so that could be used ! 411: * here. The reason the rounding is needed is so that the ! 412: * decimal version of the smallest denorm will not become 0. ! 413: */ ! 414: #else /* !defined(NeXT) */ ! 415: /* Round the mantissa up, but don't change the number */ ! 416: #endif /* NeXT */ ! 417: if(next_bits(1)) { ! 418: --lp; ! 419: if(prec_bits>LITTLENUM_NUMBER_OF_BITS) { ! 420: int n = 0; ! 421: int tmp_bits; ! 422: ! 423: n=0; ! 424: tmp_bits=prec_bits; ! 425: while(tmp_bits>LITTLENUM_NUMBER_OF_BITS) { ! 426: if(lp[n]!=(LITTLENUM_TYPE)-1) ! 427: break; ! 428: --n; ! 429: tmp_bits-=LITTLENUM_NUMBER_OF_BITS; ! 430: } ! 431: #ifndef NeXT ! 432: if(tmp_bits>LITTLENUM_NUMBER_OF_BITS || ! 433: (lp[n]&mask[tmp_bits])!=mask[tmp_bits]) ! 434: #endif NeXT ! 435: { ! 436: unsigned long int carry; ! 437: ! 438: for (carry = 1; carry && (lp >= words); lp --) { ! 439: carry = * lp + carry; ! 440: * lp = carry; ! 441: carry >>= LITTLENUM_NUMBER_OF_BITS; ! 442: } ! 443: } ! 444: } ! 445: else ! 446: #ifdef NeXT ! 447: *lp = *lp + 1; ! 448: #else /* !defined(NeXT) */ ! 449: else if((*lp&mask[prec_bits])!=mask[prec_bits]) ! 450: *lp++; ! 451: #endif /* NeXT */ ! 452: } ! 453: ! 454: return return_value; ! 455: } else if (exponent_4 & ~ mask [exponent_bits]) { ! 456: /* ! 457: * Exponent overflow. Lose immediately. ! 458: */ ! 459: ! 460: /* ! 461: * We leave return_value alone: admit we read the ! 462: * number, but return a floating exception ! 463: * because we can't encode the number. ! 464: */ ! 465: #ifdef NeXT ! 466: if(precision==F_PRECISION) { ! 467: words[0]=0x7f80; ! 468: words[1]=0; ! 469: } else { ! 470: words[0]=0x7ff0; ! 471: words[1]=0; ! 472: words[2]=0; ! 473: words[3]=0; ! 474: } ! 475: if(generic_floating_point_number.sign=='-') ! 476: words[0] |= 0x8000; ! 477: #else /* NeXT */ ! 478: make_invalid_floating_point_number (words); ! 479: #endif /* NeXT */ ! 480: return return_value; ! 481: } else { ! 482: word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits)) ! 483: | next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits); ! 484: } ! 485: ! 486: * lp ++ = word1; ! 487: ! 488: /* X_PRECISION is special: it has 16 bits of zero in the middle, ! 489: followed by a 1 bit. */ ! 490: if(exponent_bits==15 && precision==X_PRECISION) { ! 491: *lp++=0; ! 492: *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1) | ! 493: next_bits(LITTLENUM_NUMBER_OF_BITS - 1); ! 494: } ! 495: ! 496: /* The rest of the words are just mantissa bits. */ ! 497: while(lp < words + precision) ! 498: *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); ! 499: ! 500: if (next_bits (1)) { ! 501: unsigned long int carry; ! 502: /* ! 503: * Since the NEXT bit is a 1, round UP the mantissa. ! 504: * The cunning design of these hidden-1 floats permits ! 505: * us to let the mantissa overflow into the exponent, and ! 506: * it 'does the right thing'. However, we lose if the ! 507: * highest-order bit of the lowest-order word flips. ! 508: * Is that clear? ! 509: */ ! 510: ! 511: ! 512: /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) ! 513: Please allow at least 1 more bit in carry than is in a LITTLENUM. ! 514: We need that extra bit to hold a carry during a LITTLENUM carry ! 515: propagation. Another extra bit (kept 0) will assure us that we ! 516: don't get a sticky sign bit after shifting right, and that ! 517: permits us to propagate the carry without any masking of bits. ! 518: #endif */ ! 519: for (carry = 1, lp --; carry && (lp >= words); lp --) { ! 520: carry = * lp + carry; ! 521: * lp = carry; ! 522: carry >>= LITTLENUM_NUMBER_OF_BITS; ! 523: } ! 524: if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) { ! 525: /* We leave return_value alone: admit we read the ! 526: * number, but return a floating exception ! 527: * because we can't encode the number. ! 528: */ ! 529: *words&= ~ (1 << (LITTLENUM_NUMBER_OF_BITS - 1)); ! 530: /* make_invalid_floating_point_number (words); */ ! 531: /* return return_value; */ ! 532: } ! 533: } ! 534: return (return_value); ! 535: } ! 536: ! 537: /* This routine is a real kludge. Someone really should do it better, but ! 538: I'm too lazy, and I don't understand this stuff all too well anyway ! 539: (JF) ! 540: */ ! 541: void ! 542: int_to_gen( ! 543: long x) ! 544: { ! 545: char buf[20]; ! 546: char *bufp; ! 547: ! 548: sprintf(buf,"%ld",x); ! 549: bufp= &buf[0]; ! 550: if(atof_generic(&bufp,".", md_EXP_CHARS, &generic_floating_point_number)) ! 551: as_warn("Error converting number to floating point (Exponent overflow?)"); ! 552: } ! 553: ! 554: #ifdef TEST ! 555: char * ! 556: print_gen(gen) ! 557: FLONUM_TYPE *gen; ! 558: { ! 559: FLONUM_TYPE f; ! 560: LITTLENUM_TYPE arr[10]; ! 561: double dv; ! 562: float fv; ! 563: static char sbuf[40]; ! 564: ! 565: if(gen) { ! 566: f=generic_floating_point_number; ! 567: generic_floating_point_number= *gen; ! 568: } ! 569: gen_to_words(&arr[0],4,11); ! 570: memcpy(&dv, &arr[0], sizeof(double)); ! 571: sprintf(sbuf,"%x %x %x %x %.14G ",arr[0],arr[1],arr[2],arr[3],dv); ! 572: gen_to_words(&arr[0],2,8); ! 573: memcpy(&fv, &arr[0], sizeof(float)); ! 574: sprintf(sbuf+strlen(sbuf),"%x %x %.12g\n",arr[0],arr[1],fv); ! 575: if(gen) ! 576: generic_floating_point_number=f; ! 577: return sbuf; ! 578: } ! 579: #endif /* TEST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.