|
|
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.