|
|
1.1 ! root 1: /* atof_vax.c - */ ! 2: ! 3: /* Copyright (C) 1987 Free Software Foundation, Inc. ! 4: ! 5: This file is part of Gas, the GNU Assembler. ! 6: ! 7: The GNU assembler is distributed in the hope that it will be ! 8: useful, but WITHOUT ANY WARRANTY. No author or distributor ! 9: accepts responsibility to anyone for the consequences of using it ! 10: or for whether it serves any particular purpose or works at all, ! 11: unless he says so in writing. Refer to the GNU Assembler General ! 12: Public License for full details. ! 13: ! 14: Everyone is granted permission to copy, modify and redistribute ! 15: the GNU Assembler, but only under the conditions described in the ! 16: GNU Assembler General Public License. A copy of this license is ! 17: supposed to have been given to you along with the GNU Assembler ! 18: so you can know your rights and responsibilities. It should be ! 19: in a file named COPYING. Among other things, the copyright ! 20: notice and this notice must be preserved on all copies. */ ! 21: ! 22: /* JF added these two for md_atof() */ ! 23: #include "as.h" ! 24: #include "read.h" ! 25: ! 26: #include "flonum.h" ! 27: ! 28: ! 29: /* Precision in LittleNums. */ ! 30: #define MAX_PRECISION (8) ! 31: #define H_PRECISION (8) ! 32: #define G_PRECISION (4) ! 33: #define D_PRECISION (4) ! 34: #define F_PRECISION (2) ! 35: ! 36: /* Length in LittleNums of guard bits. */ ! 37: #define GUARD (2) ! 38: ! 39: int /* Number of chars in flonum type 'letter'. */ ! 40: atof_vax_sizeof (letter) ! 41: char letter; ! 42: { ! 43: int return_value; ! 44: ! 45: /* ! 46: * Permitting uppercase letters is probably a bad idea. ! 47: * Please use only lower-cased letters in case the upper-cased ! 48: * ones become unsupported! ! 49: */ ! 50: switch (letter) ! 51: { ! 52: case 'f': ! 53: case 'F': ! 54: return_value = 4; ! 55: break; ! 56: ! 57: case 'd': ! 58: case 'D': ! 59: case 'g': ! 60: case 'G': ! 61: return_value = 8; ! 62: break; ! 63: ! 64: case 'h': ! 65: case 'H': ! 66: return_value = 16; ! 67: break; ! 68: ! 69: default: ! 70: return_value = 0; ! 71: break; ! 72: } ! 73: return (return_value); ! 74: } /* atof_vax_sizeof */ ! 75: ! 76: static long int mask [] = { ! 77: 0x00000000, ! 78: 0x00000001, ! 79: 0x00000003, ! 80: 0x00000007, ! 81: 0x0000000f, ! 82: 0x0000001f, ! 83: 0x0000003f, ! 84: 0x0000007f, ! 85: 0x000000ff, ! 86: 0x000001ff, ! 87: 0x000003ff, ! 88: 0x000007ff, ! 89: 0x00000fff, ! 90: 0x00001fff, ! 91: 0x00003fff, ! 92: 0x00007fff, ! 93: 0x0000ffff, ! 94: 0x0001ffff, ! 95: 0x0003ffff, ! 96: 0x0007ffff, ! 97: 0x000fffff, ! 98: 0x001fffff, ! 99: 0x003fffff, ! 100: 0x007fffff, ! 101: 0x00ffffff, ! 102: 0x01ffffff, ! 103: 0x03ffffff, ! 104: 0x07ffffff, ! 105: 0x0fffffff, ! 106: 0x1fffffff, ! 107: 0x3fffffff, ! 108: 0x7fffffff, ! 109: 0xffffffff ! 110: }; ! 111: ! 112: static int ! 113: next_bits (number_of_bits, address_of_bits_left_in_littlenum, address_of_littlenum_pointer) ! 114: int number_of_bits; ! 115: int * address_of_bits_left_in_littlenum; ! 116: LITTLENUM_TYPE ** address_of_littlenum_pointer; ! 117: { ! 118: int return_value; ! 119: ! 120: if (number_of_bits >= (* address_of_bits_left_in_littlenum)) ! 121: { ! 122: return_value = mask [(* address_of_bits_left_in_littlenum)] & * (* address_of_littlenum_pointer); ! 123: number_of_bits -= (* address_of_bits_left_in_littlenum); ! 124: return_value <<= number_of_bits; ! 125: (* address_of_bits_left_in_littlenum) = LITTLENUM_NUMBER_OF_BITS - number_of_bits; ! 126: (* address_of_littlenum_pointer) --; ! 127: return_value |= ( (* (* address_of_littlenum_pointer)) >> ((* address_of_bits_left_in_littlenum)) ) & mask [number_of_bits]; ! 128: } ! 129: else ! 130: { ! 131: (* address_of_bits_left_in_littlenum) -= number_of_bits; ! 132: return_value = mask [number_of_bits] & ( (* (* address_of_littlenum_pointer)) >> (* address_of_bits_left_in_littlenum)); ! 133: } ! 134: return (return_value); ! 135: } ! 136: ! 137: static void ! 138: make_invalid_floating_point_number (words) ! 139: LITTLENUM_TYPE * words; ! 140: { ! 141: * words = 0x8000; /* Floating Reserved Operand Code */ ! 142: } ! 143: ! 144: static int /* 0 means letter is OK. */ ! 145: what_kind_of_float (letter, precisionP, exponent_bitsP) ! 146: char letter; /* In: lowercase please. What kind of float? */ ! 147: int * precisionP; /* Number of 16-bit words in the float. */ ! 148: long int * exponent_bitsP; /* Number of exponent bits. */ ! 149: { ! 150: int retval; /* 0: OK. */ ! 151: ! 152: retval = 0; ! 153: switch (letter) ! 154: { ! 155: case 'f': ! 156: * precisionP = F_PRECISION; ! 157: * exponent_bitsP = 8; ! 158: break; ! 159: ! 160: case 'd': ! 161: * precisionP = D_PRECISION; ! 162: * exponent_bitsP = 8; ! 163: break; ! 164: ! 165: case 'g': ! 166: * precisionP = G_PRECISION; ! 167: * exponent_bitsP = 11; ! 168: break; ! 169: ! 170: case 'h': ! 171: * precisionP = H_PRECISION; ! 172: * exponent_bitsP = 15; ! 173: break; ! 174: ! 175: default: ! 176: retval = 69; ! 177: break; ! 178: } ! 179: return (retval); ! 180: } ! 181: ! 182: /***********************************************************************\ ! 183: * * ! 184: * Warning: this returns 16-bit LITTLENUMs, because that is * ! 185: * what the VAX thinks in. It is up to the caller to figure * ! 186: * out any alignment problems and to conspire for the bytes/word * ! 187: * to be emitted in the right order. Bigendians beware! * ! 188: * * ! 189: \***********************************************************************/ ! 190: ! 191: char * /* Return pointer past text consumed. */ ! 192: atof_vax (str, what_kind, words) ! 193: char * str; /* Text to convert to binary. */ ! 194: char what_kind; /* 'd', 'f', 'g', 'h' */ ! 195: LITTLENUM_TYPE * words; /* Build the binary here. */ ! 196: { ! 197: FLONUM_TYPE f; ! 198: LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD]; ! 199: /* Extra bits for zeroed low-order bits. */ ! 200: /* The 1st MAX_PRECISION are zeroed, */ ! 201: /* the last contain flonum bits. */ ! 202: char * return_value; ! 203: int precision; /* Number of 16-bit words in the format. */ ! 204: long int exponent_bits; ! 205: ! 206: return_value = str; ! 207: f . low = bits + MAX_PRECISION; ! 208: f . high = NULL; ! 209: f . leader = NULL; ! 210: f . exponent = NULL; ! 211: f . sign = '\0'; ! 212: ! 213: if (what_kind_of_float (what_kind, & precision, & exponent_bits)) ! 214: { ! 215: return_value = NULL; /* We lost. */ ! 216: make_invalid_floating_point_number (words); ! 217: } ! 218: if (return_value) ! 219: { ! 220: bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION); ! 221: ! 222: /* Use more LittleNums than seems */ ! 223: /* necessary: the highest flonum may have */ ! 224: /* 15 leading 0 bits, so could be useless. */ ! 225: f . high = f . low + precision - 1 + GUARD; ! 226: ! 227: if (atof_generic (& return_value, ".", "eE", & f)) ! 228: { ! 229: make_invalid_floating_point_number (words); ! 230: return_value = NULL; /* we lost */ ! 231: } ! 232: else ! 233: { ! 234: if (flonum_gen2vax (what_kind, & f, words)) ! 235: { ! 236: return_value = NULL; ! 237: } ! 238: } ! 239: } ! 240: return (return_value); ! 241: } ! 242: ! 243: /* ! 244: * In: a flonum, a vax floating point format. ! 245: * Out: a vax floating-point bit pattern. ! 246: */ ! 247: ! 248: int /* 0: OK. */ ! 249: flonum_gen2vax (format_letter, f, words) ! 250: char format_letter; /* One of 'd' 'f' 'g' 'h'. */ ! 251: FLONUM_TYPE * f; ! 252: LITTLENUM_TYPE * words; /* Deliver answer here. */ ! 253: { ! 254: int bits_left_in_littlenum; ! 255: LITTLENUM_TYPE * littlenum_pointer; ! 256: LITTLENUM_TYPE * lp; ! 257: int precision; ! 258: long int exponent_bits; ! 259: int return_value; /* 0 == OK. */ ! 260: ! 261: return_value = what_kind_of_float (format_letter, & precision, & exponent_bits); ! 262: if (return_value != 0) ! 263: { ! 264: make_invalid_floating_point_number (words); ! 265: } ! 266: else ! 267: { ! 268: if (f -> low > f -> leader) ! 269: { ! 270: /* 0.0e0 seen. */ ! 271: bzero (words, sizeof(LITTLENUM_TYPE) * precision); ! 272: } ! 273: else ! 274: { ! 275: long int exponent_1; ! 276: long int exponent_2; ! 277: long int exponent_3; ! 278: long int exponent_4; ! 279: int exponent_skippage; ! 280: LITTLENUM_TYPE word1; ! 281: ! 282: /* ! 283: * All vaxen floating_point formats (so far) have: ! 284: * Bit 15 is sign bit. ! 285: * Bits 14:n are excess-whatever exponent. ! 286: * Bits n-1:0 (if any) are most significant bits of fraction. ! 287: * Bits 15:0 of the next word are the next most significant bits. ! 288: * And so on for each other word. ! 289: * ! 290: * All this to be compatible with a KF11?? (Which is still faster ! 291: * than lots of vaxen I can think of, but it also has higher ! 292: * maintenance costs ... sigh). ! 293: * ! 294: * So we need: number of bits of exponent, number of bits of ! 295: * mantissa. ! 296: */ ! 297: ! 298: #ifdef NEVER /******* This zeroing seems redundant - Dean 3may86 **********/ ! 299: /* ! 300: * No matter how few bits we got back from the atof() ! 301: * routine, add enough zero littlenums so the rest of the ! 302: * code won't run out of "significant" bits in the mantissa. ! 303: */ ! 304: { ! 305: LITTLENUM_TYPE * ltp; ! 306: for (ltp = f -> leader + 1; ! 307: ltp <= f -> low + precision; ! 308: ltp ++) ! 309: { ! 310: * ltp = 0; ! 311: } ! 312: } ! 313: #endif ! 314: ! 315: bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; ! 316: littlenum_pointer = f -> leader; ! 317: /* Seek (and forget) 1st significant bit */ ! 318: for (exponent_skippage = 0; ! 319: ! next_bits(1, &bits_left_in_littlenum, &littlenum_pointer); ! 320: exponent_skippage ++) ! 321: { ! 322: } ! 323: exponent_1 = f -> exponent + f -> leader + 1 - f -> low; ! 324: /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */ ! 325: exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; ! 326: /* Radix 2. */ ! 327: exponent_3 = exponent_2 - exponent_skippage; ! 328: /* Forget leading zeros, forget 1st bit. */ ! 329: exponent_4 = exponent_3 + (1 << (exponent_bits - 1)); ! 330: /* Offset exponent. */ ! 331: ! 332: if (exponent_4 & ~ mask [exponent_bits]) ! 333: { ! 334: /* ! 335: * Exponent overflow. Lose immediately. ! 336: */ ! 337: ! 338: make_invalid_floating_point_number (words); ! 339: ! 340: /* ! 341: * We leave return_value alone: admit we read the ! 342: * number, but return a floating exception ! 343: * because we can't encode the number. ! 344: */ ! 345: } ! 346: else ! 347: { ! 348: lp = words; ! 349: ! 350: /* Word 1. Sign, exponent and perhaps high bits. */ ! 351: /* Assume 2's complement integers. */ ! 352: word1 = ((exponent_4 & mask [exponent_bits]) << (15 - exponent_bits)) ! 353: | ((f -> sign == '+') ? 0 : 0x8000) ! 354: | next_bits (15 - exponent_bits, &bits_left_in_littlenum, &littlenum_pointer); ! 355: * lp ++ = word1; ! 356: ! 357: /* The rest of the words are just mantissa bits. */ ! 358: for (; lp < words + precision; lp++) ! 359: { ! 360: * lp = next_bits (LITTLENUM_NUMBER_OF_BITS, &bits_left_in_littlenum, &littlenum_pointer); ! 361: } ! 362: ! 363: if (next_bits (1, &bits_left_in_littlenum, &littlenum_pointer)) ! 364: { ! 365: /* ! 366: * Since the NEXT bit is a 1, round UP the mantissa. ! 367: * The cunning design of these hidden-1 floats permits ! 368: * us to let the mantissa overflow into the exponent, and ! 369: * it 'does the right thing'. However, we lose if the ! 370: * highest-order bit of the lowest-order word flips. ! 371: * Is that clear? ! 372: */ ! 373: ! 374: unsigned long int carry; ! 375: ! 376: /* ! 377: #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) ! 378: Please allow at least 1 more bit in carry than is in a LITTLENUM. ! 379: We need that extra bit to hold a carry during a LITTLENUM carry ! 380: propagation. Another extra bit (kept 0) will assure us that we ! 381: don't get a sticky sign bit after shifting right, and that ! 382: permits us to propagate the carry without any masking of bits. ! 383: #endif ! 384: */ ! 385: for (carry = 1, lp --; ! 386: carry && (lp >= words); ! 387: lp --) ! 388: { ! 389: carry = * lp + carry; ! 390: * lp = carry; ! 391: carry >>= LITTLENUM_NUMBER_OF_BITS; ! 392: } ! 393: ! 394: if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) ! 395: { ! 396: make_invalid_floating_point_number (words); ! 397: /* ! 398: * We leave return_value alone: admit we read the ! 399: * number, but return a floating exception ! 400: * because we can't encode the number. ! 401: */ ! 402: } ! 403: } /* if (we needed to round up) */ ! 404: } /* if (exponent overflow) */ ! 405: } /* if (0.0e0) */ ! 406: } /* if (float_type was OK) */ ! 407: return (return_value); ! 408: } ! 409: ! 410: ! 411: /* JF this used to be in vax.c but this looks like a better place for it */ ! 412: ! 413: /* ! 414: * md_atof() ! 415: * ! 416: * In: input_line_pointer -> the 1st character of a floating-point ! 417: * number. ! 418: * 1 letter denoting the type of statement that wants a ! 419: * binary floating point number returned. ! 420: * Address of where to build floating point literal. ! 421: * Assumed to be 'big enough'. ! 422: * Address of where to return size of literal (in chars). ! 423: * ! 424: * Out: Input_line_pointer -> of next char after floating number. ! 425: * Error message, or "". ! 426: * Floating point literal. ! 427: * Number of chars we used for the literal. ! 428: */ ! 429: ! 430: int atof_vax_sizeof(); ! 431: ! 432: #define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */ ! 433: ! 434: char * ! 435: md_atof (what_statement_type, literalP, sizeP) ! 436: char what_statement_type; ! 437: char * literalP; ! 438: int * sizeP; ! 439: { ! 440: LITTLENUM_TYPE words [MAXIMUM_NUMBER_OF_LITTLENUMS]; ! 441: register char kind_of_float; ! 442: register int number_of_chars; ! 443: register LITTLENUM_TYPE * littlenum_pointer; ! 444: ! 445: switch (what_statement_type) ! 446: { ! 447: case 'F': /* .float */ ! 448: case 'f': /* .ffloat */ ! 449: kind_of_float = 'f'; ! 450: break; ! 451: ! 452: case 'D': /* .double */ ! 453: case 'd': /* .dfloat */ ! 454: kind_of_float = 'd'; ! 455: break; ! 456: ! 457: case 'g': /* .gfloat */ ! 458: kind_of_float = 'g'; ! 459: break; ! 460: ! 461: case 'h': /* .hfloat */ ! 462: kind_of_float = 'h'; ! 463: break; ! 464: ! 465: default: ! 466: kind_of_float = 0; ! 467: break; ! 468: }; ! 469: ! 470: if (kind_of_float) ! 471: { ! 472: register LITTLENUM_TYPE * limit; ! 473: char * atof_vax(); ! 474: ! 475: input_line_pointer = atof_vax (input_line_pointer, ! 476: kind_of_float, ! 477: words); ! 478: /* ! 479: * The atof_vax() builds up 16-bit numbers. ! 480: * Since the assembler may not be running on ! 481: * a little-endian machine, be very careful about ! 482: * converting words to chars. ! 483: */ ! 484: number_of_chars = atof_vax_sizeof (kind_of_float); ! 485: know( number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof(LITTLENUM_TYPE) ); ! 486: limit = words + (number_of_chars / sizeof(LITTLENUM_TYPE)); ! 487: for (littlenum_pointer = words; ! 488: littlenum_pointer < limit; ! 489: littlenum_pointer ++) ! 490: { ! 491: md_number_to_chars (literalP, * littlenum_pointer, sizeof(LITTLENUM_TYPE)); ! 492: literalP += sizeof(LITTLENUM_TYPE); ! 493: }; ! 494: } ! 495: else ! 496: { ! 497: number_of_chars = 0; ! 498: }; ! 499: ! 500: * sizeP = number_of_chars; ! 501: return (kind_of_float ? "" : "Bad call to md_atof()"); ! 502: } /* md_atof() */ ! 503: ! 504: /* atof_vax.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.