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