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