|
|
1.1 ! root 1: /* atof_i386.c -- turn a Flonum into an i386 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 "flonum.h" ! 21: #ifdef USG ! 22: #define bzero(s,n) memset(s,0,n) ! 23: #endif ! 24: ! 25: extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */ ! 26: #define NULL (0) ! 27: ! 28: extern char EXP_CHARS[]; ! 29: /* Precision in LittleNums. */ ! 30: #define MAX_PRECISION (6) ! 31: #define F_PRECISION (2) ! 32: #define D_PRECISION (4) ! 33: #define X_PRECISION (5) ! 34: ! 35: /* Length in LittleNums of guard bits. */ ! 36: #define GUARD (2) ! 37: ! 38: int /* Number of chars in flonum type 'letter'. */ ! 39: atof_sizeof (letter) ! 40: char letter; ! 41: { ! 42: int return_value; ! 43: ! 44: /* ! 45: * Permitting uppercase letters is probably a bad idea. ! 46: * Please use only lower-cased letters in case the upper-cased ! 47: * ones become unsupported! ! 48: */ ! 49: switch (letter) ! 50: { ! 51: case 'f': ! 52: case 'F': ! 53: return_value = F_PRECISION; ! 54: break; ! 55: ! 56: case 'd': ! 57: case 'D': ! 58: return_value = D_PRECISION; ! 59: break; ! 60: ! 61: case 'x': ! 62: case 'X': ! 63: return_value = X_PRECISION; ! 64: break; ! 65: ! 66: default: ! 67: return_value = 0; ! 68: break; ! 69: } ! 70: return (return_value); ! 71: } ! 72: ! 73: static unsigned long int mask [] = { ! 74: 0x00000000, ! 75: 0x00000001, ! 76: 0x00000003, ! 77: 0x00000007, ! 78: 0x0000000f, ! 79: 0x0000001f, ! 80: 0x0000003f, ! 81: 0x0000007f, ! 82: 0x000000ff, ! 83: 0x000001ff, ! 84: 0x000003ff, ! 85: 0x000007ff, ! 86: 0x00000fff, ! 87: 0x00001fff, ! 88: 0x00003fff, ! 89: 0x00007fff, ! 90: 0x0000ffff, ! 91: 0x0001ffff, ! 92: 0x0003ffff, ! 93: 0x0007ffff, ! 94: 0x000fffff, ! 95: 0x001fffff, ! 96: 0x003fffff, ! 97: 0x007fffff, ! 98: 0x00ffffff, ! 99: 0x01ffffff, ! 100: 0x03ffffff, ! 101: 0x07ffffff, ! 102: 0x0fffffff, ! 103: 0x1fffffff, ! 104: 0x3fffffff, ! 105: 0x7fffffff, ! 106: 0xffffffff ! 107: }; ! 108: ! 109: static int bits_left_in_littlenum; ! 110: static int littlenums_left; ! 111: static LITTLENUM_TYPE * littlenum_pointer; ! 112: ! 113: static int ! 114: next_bits (number_of_bits) ! 115: int number_of_bits; ! 116: { ! 117: int return_value; ! 118: ! 119: if(!littlenums_left) ! 120: return 0; ! 121: if (number_of_bits >= bits_left_in_littlenum) { ! 122: return_value = mask [bits_left_in_littlenum] & *littlenum_pointer; ! 123: number_of_bits -= bits_left_in_littlenum; ! 124: return_value <<= number_of_bits; ! 125: if(littlenums_left) { ! 126: bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; ! 127: littlenum_pointer --; ! 128: --littlenums_left; ! 129: return_value |= ! 130: (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits]; ! 131: } ! 132: } else { ! 133: bits_left_in_littlenum -= number_of_bits; ! 134: return_value = ! 135: mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum); ! 136: } ! 137: return (return_value); ! 138: } ! 139: ! 140: static void ! 141: make_invalid_floating_point_number (words, precision) ! 142: LITTLENUM_TYPE * words; ! 143: int precision; ! 144: { ! 145: bzero (words, precision * sizeof (LITTLENUM_TYPE)); ! 146: switch (precision) { ! 147: case F_PRECISION: ! 148: words[0] = 0xffc0; break; ! 149: case D_PRECISION: ! 150: words[0] = 0xfff8; break; ! 151: case X_PRECISION: ! 152: words[0] = 0xffff; words[1] = 0xc000; break; ! 153: } ! 154: } ! 155: ! 156: /***********************************************************************\ ! 157: * * ! 158: * Warning: this returns 16-bit LITTLENUMs, because that is * ! 159: * what the VAX thinks in. It is up to the caller to figure * ! 160: * out any alignment problems and to conspire for the bytes/word * ! 161: * to be emitted in the right order. Bigendians beware! * ! 162: * * ! 163: \***********************************************************************/ ! 164: ! 165: char * /* Return pointer past text consumed. */ ! 166: atof_i386 (str, what_kind, words) ! 167: char * str; /* Text to convert to binary. */ ! 168: char what_kind; /* 'd', 'f', 'g', 'h' */ ! 169: LITTLENUM_TYPE * words; /* Build the binary here. */ ! 170: { ! 171: FLONUM_TYPE f; ! 172: LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; ! 173: /* Extra bits for zeroed low-order bits. */ ! 174: /* The 1st MAX_PRECISION are zeroed, */ ! 175: /* the last contain flonum bits. */ ! 176: char * return_value; ! 177: int precision; /* Number of 16-bit words in the format. */ ! 178: long int exponent_bits; ! 179: ! 180: long int exponent_1; ! 181: long int exponent_2; ! 182: long int exponent_3; ! 183: long int exponent_4; ! 184: int exponent_skippage; ! 185: LITTLENUM_TYPE word1; ! 186: LITTLENUM_TYPE * lp; ! 187: ! 188: return_value = str; ! 189: f.low = bits + MAX_PRECISION; ! 190: f.high = NULL; ! 191: f.leader = NULL; ! 192: f.exponent = NULL; ! 193: f.sign = '\0'; ! 194: ! 195: /* Use more LittleNums than seems */ ! 196: /* necessary: the highest flonum may have */ ! 197: /* 15 leading 0 bits, so could be useless. */ ! 198: ! 199: bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION); ! 200: ! 201: switch(what_kind) { ! 202: case 'f': ! 203: case 'F': ! 204: precision = F_PRECISION; ! 205: exponent_bits = 8; ! 206: break; ! 207: ! 208: case 'd': ! 209: case 'D': ! 210: precision = D_PRECISION; ! 211: exponent_bits = 11; ! 212: break; ! 213: ! 214: case 'x': ! 215: case 'X': ! 216: precision = X_PRECISION; ! 217: exponent_bits = 15; ! 218: break; ! 219: ! 220: default: ! 221: make_invalid_floating_point_number (words, precision); ! 222: return NULL; ! 223: } ! 224: ! 225: f.high = f.low + precision - 1 + GUARD; ! 226: ! 227: if (atof_generic (& return_value, ".", EXP_CHARS, & f)) { ! 228: as_warn("Error converting floating point number (Exponent overflow?)"); ! 229: make_invalid_floating_point_number (words, precision); ! 230: return NULL; ! 231: } ! 232: ! 233: if (f.low > f.leader) { ! 234: /* 0.0e0 seen. */ ! 235: bzero (words, sizeof(LITTLENUM_TYPE) * precision); ! 236: return return_value; ! 237: } ! 238: ! 239: if(f.sign!='+' && f.sign!='-') { ! 240: make_invalid_floating_point_number(words,precision); ! 241: return NULL; ! 242: } ! 243: /* ! 244: * All vaxen floating_point formats (so far) have: ! 245: * Bit 15 is sign bit. ! 246: * Bits 14:n are excess-whatever exponent. ! 247: * Bits n-1:0 (if any) are most significant bits of fraction. ! 248: * Bits 15:0 of the next word are the next most significant bits. ! 249: * And so on for each other word. ! 250: * ! 251: * So we need: number of bits of exponent, number of bits of ! 252: * mantissa. ! 253: */ ! 254: bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; ! 255: littlenum_pointer = f.leader; ! 256: littlenums_left = 1 + f.leader-f.low; ! 257: if (precision != X_PRECISION) { ! 258: /* Seek (and forget) 1st significant bit */ ! 259: for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ; ! 260: } else { ! 261: /* Dont seek (and forget) 1st significant bit for X format */ ! 262: for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ; ! 263: exponent_skippage--; ! 264: bits_left_in_littlenum++; ! 265: } ! 266: exponent_1 = f.exponent + f.leader + 1 - f.low; ! 267: /* Radix LITTLENUM_RADIX, point just higher than f.leader. */ ! 268: exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; ! 269: /* Radix 2. */ ! 270: exponent_3 = exponent_2 - exponent_skippage; ! 271: /* Forget leading zeros, forget 1st bit. */ ! 272: exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); ! 273: /* Offset exponent. */ ! 274: ! 275: if (exponent_4 & ~ mask [exponent_bits]) { ! 276: /* ! 277: * Exponent overflow. Lose immediately. ! 278: */ ! 279: ! 280: /* ! 281: * We leave return_value alone: admit we read the ! 282: * number, but return a floating exception ! 283: * because we can't encode the number. ! 284: */ ! 285: ! 286: as_warn("Exponent overflow in floating-point number"); ! 287: make_invalid_floating_point_number (words, precision); ! 288: return return_value; ! 289: } ! 290: lp = words; ! 291: ! 292: /* Word 1. Sign, exponent and perhaps high bits. */ ! 293: /* Assume 2's complement integers. */ ! 294: word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)); ! 295: word1 |= ((f.sign == '+') ? 0 : 0x8000); ! 296: word1 |= next_bits (15 - exponent_bits); ! 297: * lp ++ = word1; ! 298: ! 299: /* The rest of the words are just mantissa bits. */ ! 300: for (; lp < words + precision; lp++) ! 301: * lp = next_bits (LITTLENUM_NUMBER_OF_BITS); ! 302: ! 303: if (next_bits (1)) { ! 304: unsigned long int carry; ! 305: /* ! 306: * Since the NEXT bit is a 1, round UP the mantissa. ! 307: * The cunning design of these hidden-1 floats permits ! 308: * us to let the mantissa overflow into the exponent, and ! 309: * it 'does the right thing'. However, we lose if the ! 310: * highest-order bit of the lowest-order word flips. ! 311: * Is that clear? ! 312: */ ! 313: ! 314: ! 315: /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) ! 316: Please allow at least 1 more bit in carry than is in a LITTLENUM. ! 317: We need that extra bit to hold a carry during a LITTLENUM carry ! 318: propagation. Another extra bit (kept 0) will assure us that we ! 319: don't get a sticky sign bit after shifting right, and that ! 320: permits us to propagate the carry without any masking of bits. ! 321: #endif */ ! 322: for (carry = 1, lp --; carry && (lp >= words); lp --) { ! 323: carry = * lp + carry; ! 324: * lp = carry; ! 325: carry >>= LITTLENUM_NUMBER_OF_BITS; ! 326: } ! 327: if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) { ! 328: /* We leave return_value alone: admit we read the ! 329: * number, but return a floating exception ! 330: * because we can't encode the number. ! 331: */ ! 332: make_invalid_floating_point_number (words, precision); ! 333: return return_value; ! 334: } ! 335: } ! 336: return (return_value); ! 337: } ! 338: ! 339: /* This is really identical to atof_m68k except for some details */ ! 340: ! 341: gen_to_words(words,precision,exponent_bits) ! 342: LITTLENUM_TYPE *words; ! 343: long int exponent_bits; ! 344: { ! 345: int return_value=0; ! 346: ! 347: long int exponent_1; ! 348: long int exponent_2; ! 349: long int exponent_3; ! 350: long int exponent_4; ! 351: int exponent_skippage; ! 352: LITTLENUM_TYPE word1; ! 353: LITTLENUM_TYPE * lp; ! 354: ! 355: if (generic_floating_point_number.low > generic_floating_point_number.leader) { ! 356: /* 0.0e0 seen. */ ! 357: bzero (words, sizeof(LITTLENUM_TYPE) * precision); ! 358: return return_value; ! 359: } ! 360: ! 361: /* ! 362: * All vaxen floating_point formats (so far) have: ! 363: * Bit 15 is sign bit. ! 364: * Bits 14:n are excess-whatever exponent. ! 365: * Bits n-1:0 (if any) are most significant bits of fraction. ! 366: * Bits 15:0 of the next word are the next most significant bits. ! 367: * And so on for each other word. ! 368: * ! 369: * So we need: number of bits of exponent, number of bits of ! 370: * mantissa. ! 371: */ ! 372: bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; ! 373: littlenum_pointer = generic_floating_point_number.leader; ! 374: littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low; ! 375: /* Seek (and forget) 1st significant bit */ ! 376: for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++) ! 377: ; ! 378: exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 - ! 379: generic_floating_point_number.low; ! 380: /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */ ! 381: exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; ! 382: /* Radix 2. */ ! 383: exponent_3 = exponent_2 - exponent_skippage; ! 384: /* Forget leading zeros, forget 1st bit. */ ! 385: exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); ! 386: /* Offset exponent. */ ! 387: ! 388: if (exponent_4 & ~ mask [exponent_bits]) { ! 389: /* ! 390: * Exponent overflow. Lose immediately. ! 391: */ ! 392: ! 393: /* ! 394: * We leave return_value alone: admit we read the ! 395: * number, but return a floating exception ! 396: * because we can't encode the number. ! 397: */ ! 398: ! 399: make_invalid_floating_point_number (words, precision); ! 400: return return_value; ! 401: } ! 402: lp = words; ! 403: ! 404: /* Word 1. Sign, exponent and perhaps high bits. */ ! 405: /* Assume 2's complement integers. */ ! 406: word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)); ! 407: word1 |= ((generic_floating_point_number.sign == '+') ? 0 : 0x8000); ! 408: word1 |= next_bits (15 - exponent_bits); ! 409: * lp ++ = word1; ! 410: ! 411: /* The rest of the words are just mantissa bits. */ ! 412: for (; lp < words + precision; lp++) ! 413: * lp = next_bits (LITTLENUM_NUMBER_OF_BITS); ! 414: ! 415: if (next_bits (1)) { ! 416: unsigned long int carry; ! 417: /* ! 418: * Since the NEXT bit is a 1, round UP the mantissa. ! 419: * The cunning design of these hidden-1 floats permits ! 420: * us to let the mantissa overflow into the exponent, and ! 421: * it 'does the right thing'. However, we lose if the ! 422: * highest-order bit of the lowest-order word flips. ! 423: * Is that clear? ! 424: */ ! 425: ! 426: ! 427: /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) ! 428: Please allow at least 1 more bit in carry than is in a LITTLENUM. ! 429: We need that extra bit to hold a carry during a LITTLENUM carry ! 430: propagation. Another extra bit (kept 0) will assure us that we ! 431: don't get a sticky sign bit after shifting right, and that ! 432: permits us to propagate the carry without any masking of bits. ! 433: #endif */ ! 434: for (carry = 1, lp --; carry && (lp >= words); lp --) { ! 435: carry = * lp + carry; ! 436: * lp = carry; ! 437: carry >>= LITTLENUM_NUMBER_OF_BITS; ! 438: } ! 439: if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) { ! 440: /* We leave return_value alone: admit we read the ! 441: * number, but return a floating exception ! 442: * because we can't encode the number. ! 443: */ ! 444: make_invalid_floating_point_number (words, precision); ! 445: return return_value; ! 446: } ! 447: } ! 448: return (return_value); ! 449: } ! 450: ! 451: /* This routine is a real kludge. Someone really should do it better, but ! 452: I'm too lazy, and I don't understand this stuff all too well anyway ! 453: (JF) ! 454: */ ! 455: int_to_gen(x) ! 456: long x; ! 457: { ! 458: char buf[20]; ! 459: char *bufp; ! 460: ! 461: sprintf(buf,"%ld",x); ! 462: bufp= &buf[0]; ! 463: if(atof_generic(&bufp,".", EXP_CHARS, &generic_floating_point_number)) ! 464: as_warn("Error converting number to floating point (Exponent overflow?)"); ! 465: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.