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