source: trunk/binutils/gas/config/atof-ieee.c@ 2562

Last change on this file since 2562 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 18.6 KB
Line 
1/* atof_ieee.c - turn a Flonum into an IEEE floating point number
2 Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22#include "as.h"
23
24/* Flonums returned here. */
25extern FLONUM_TYPE generic_floating_point_number;
26
27static int next_bits PARAMS ((int));
28static void unget_bits PARAMS ((int));
29static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
30
31extern const char EXP_CHARS[];
32/* Precision in LittleNums. */
33/* Don't count the gap in the m68k extended precision format. */
34#define MAX_PRECISION (5)
35#define F_PRECISION (2)
36#define D_PRECISION (4)
37#define X_PRECISION (5)
38#define P_PRECISION (5)
39
40/* Length in LittleNums of guard bits. */
41#define GUARD (2)
42
43#ifndef TC_LARGEST_EXPONENT_IS_NORMAL
44#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0
45#endif
46
47static const unsigned long mask[] =
48{
49 0x00000000,
50 0x00000001,
51 0x00000003,
52 0x00000007,
53 0x0000000f,
54 0x0000001f,
55 0x0000003f,
56 0x0000007f,
57 0x000000ff,
58 0x000001ff,
59 0x000003ff,
60 0x000007ff,
61 0x00000fff,
62 0x00001fff,
63 0x00003fff,
64 0x00007fff,
65 0x0000ffff,
66 0x0001ffff,
67 0x0003ffff,
68 0x0007ffff,
69 0x000fffff,
70 0x001fffff,
71 0x003fffff,
72 0x007fffff,
73 0x00ffffff,
74 0x01ffffff,
75 0x03ffffff,
76 0x07ffffff,
77 0x0fffffff,
78 0x1fffffff,
79 0x3fffffff,
80 0x7fffffff,
81 0xffffffff,
82};
83
84
85static int bits_left_in_littlenum;
86static int littlenums_left;
87static LITTLENUM_TYPE *littlenum_pointer;
88
89static int
90next_bits (number_of_bits)
91 int number_of_bits;
92{
93 int return_value;
94
95 if (!littlenums_left)
96 return (0);
97 if (number_of_bits >= bits_left_in_littlenum)
98 {
99 return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
100 number_of_bits -= bits_left_in_littlenum;
101 return_value <<= number_of_bits;
102
103 if (--littlenums_left)
104 {
105 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
106 --littlenum_pointer;
107 return_value |=
108 (*littlenum_pointer >> bits_left_in_littlenum)
109 & mask[number_of_bits];
110 }
111 }
112 else
113 {
114 bits_left_in_littlenum -= number_of_bits;
115 return_value =
116 mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
117 }
118 return return_value;
119}
120
121/* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */
122
123static void
124unget_bits (num)
125 int num;
126{
127 if (!littlenums_left)
128 {
129 ++littlenum_pointer;
130 ++littlenums_left;
131 bits_left_in_littlenum = num;
132 }
133 else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
134 {
135 bits_left_in_littlenum =
136 num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
137 ++littlenum_pointer;
138 ++littlenums_left;
139 }
140 else
141 bits_left_in_littlenum += num;
142}
143
144static void
145make_invalid_floating_point_number (words)
146 LITTLENUM_TYPE *words;
147{
148 as_bad (_("cannot create floating-point number"));
149 /* Zero the leftmost bit. */
150 words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1;
151 words[1] = (LITTLENUM_TYPE) -1;
152 words[2] = (LITTLENUM_TYPE) -1;
153 words[3] = (LITTLENUM_TYPE) -1;
154 words[4] = (LITTLENUM_TYPE) -1;
155 words[5] = (LITTLENUM_TYPE) -1;
156}
157
158
159/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to
160 figure out any alignment problems and to conspire for the
161 bytes/word to be emitted in the right order. Bigendians beware! */
162
163/* Note that atof-ieee always has X and P precisions enabled. it is up
164 to md_atof to filter them out if the target machine does not support
165 them. */
166
167/* Returns pointer past text consumed. */
168
169char *
170atof_ieee (str, what_kind, words)
171 char *str; /* Text to convert to binary. */
172 int what_kind; /* 'd', 'f', 'g', 'h'. */
173 LITTLENUM_TYPE *words; /* Build the binary here. */
174{
175 /* Extra bits for zeroed low-order bits.
176 The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */
177 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
178 char *return_value;
179 /* Number of 16-bit words in the format. */
180 int precision;
181 long exponent_bits;
182 FLONUM_TYPE save_gen_flonum;
183
184 /* We have to save the generic_floating_point_number because it
185 contains storage allocation about the array of LITTLENUMs where
186 the value is actually stored. We will allocate our own array of
187 littlenums below, but have to restore the global one on exit. */
188 save_gen_flonum = generic_floating_point_number;
189
190 return_value = str;
191 generic_floating_point_number.low = bits + MAX_PRECISION;
192 generic_floating_point_number.high = NULL;
193 generic_floating_point_number.leader = NULL;
194 generic_floating_point_number.exponent = 0;
195 generic_floating_point_number.sign = '\0';
196
197 /* Use more LittleNums than seems necessary: the highest flonum may
198 have 15 leading 0 bits, so could be useless. */
199
200 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
201
202 switch (what_kind)
203 {
204 case 'f':
205 case 'F':
206 case 's':
207 case 'S':
208 precision = F_PRECISION;
209 exponent_bits = 8;
210 break;
211
212 case 'd':
213 case 'D':
214 case 'r':
215 case 'R':
216 precision = D_PRECISION;
217 exponent_bits = 11;
218 break;
219
220 case 'x':
221 case 'X':
222 case 'e':
223 case 'E':
224 precision = X_PRECISION;
225 exponent_bits = 15;
226 break;
227
228 case 'p':
229 case 'P':
230
231 precision = P_PRECISION;
232 exponent_bits = -1;
233 break;
234
235 default:
236 make_invalid_floating_point_number (words);
237 return (NULL);
238 }
239
240 generic_floating_point_number.high
241 = generic_floating_point_number.low + precision - 1 + GUARD;
242
243 if (atof_generic (&return_value, ".", EXP_CHARS,
244 &generic_floating_point_number))
245 {
246 make_invalid_floating_point_number (words);
247 return (NULL);
248 }
249 gen_to_words (words, precision, exponent_bits);
250
251 /* Restore the generic_floating_point_number's storage alloc (and
252 everything else). */
253 generic_floating_point_number = save_gen_flonum;
254
255 return return_value;
256}
257
258/* Turn generic_floating_point_number into a real float/double/extended. */
259
260int
261gen_to_words (words, precision, exponent_bits)
262 LITTLENUM_TYPE *words;
263 int precision;
264 long exponent_bits;
265{
266 int return_value = 0;
267
268 long exponent_1;
269 long exponent_2;
270 long exponent_3;
271 long exponent_4;
272 int exponent_skippage;
273 LITTLENUM_TYPE word1;
274 LITTLENUM_TYPE *lp;
275 LITTLENUM_TYPE *words_end;
276
277 words_end = words + precision;
278#ifdef TC_M68K
279 if (precision == X_PRECISION)
280 /* On the m68k the extended precision format has a gap of 16 bits
281 between the exponent and the mantissa. */
282 words_end++;
283#endif
284
285 if (generic_floating_point_number.low > generic_floating_point_number.leader)
286 {
287 /* 0.0e0 seen. */
288 if (generic_floating_point_number.sign == '+')
289 words[0] = 0x0000;
290 else
291 words[0] = 0x8000;
292 memset (&words[1], '\0',
293 (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
294 return return_value;
295 }
296
297 /* NaN: Do the right thing. */
298 if (generic_floating_point_number.sign == 0)
299 {
300 if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
301 as_warn ("NaNs are not supported by this target\n");
302 if (precision == F_PRECISION)
303 {
304 words[0] = 0x7fff;
305 words[1] = 0xffff;
306 }
307 else if (precision == X_PRECISION)
308 {
309#ifdef TC_M68K
310 words[0] = 0x7fff;
311 words[1] = 0;
312 words[2] = 0xffff;
313 words[3] = 0xffff;
314 words[4] = 0xffff;
315 words[5] = 0xffff;
316#else /* ! TC_M68K */
317#ifdef TC_I386
318 words[0] = 0xffff;
319 words[1] = 0xc000;
320 words[2] = 0;
321 words[3] = 0;
322 words[4] = 0;
323#else /* ! TC_I386 */
324 abort ();
325#endif /* ! TC_I386 */
326#endif /* ! TC_M68K */
327 }
328 else
329 {
330 words[0] = 0x7fff;
331 words[1] = 0xffff;
332 words[2] = 0xffff;
333 words[3] = 0xffff;
334 }
335 return return_value;
336 }
337 else if (generic_floating_point_number.sign == 'P')
338 {
339 if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
340 as_warn ("Infinities are not supported by this target\n");
341
342 /* +INF: Do the right thing. */
343 if (precision == F_PRECISION)
344 {
345 words[0] = 0x7f80;
346 words[1] = 0;
347 }
348 else if (precision == X_PRECISION)
349 {
350#ifdef TC_M68K
351 words[0] = 0x7fff;
352 words[1] = 0;
353 words[2] = 0;
354 words[3] = 0;
355 words[4] = 0;
356 words[5] = 0;
357#else /* ! TC_M68K */
358#ifdef TC_I386
359 words[0] = 0x7fff;
360 words[1] = 0x8000;
361 words[2] = 0;
362 words[3] = 0;
363 words[4] = 0;
364#else /* ! TC_I386 */
365 abort ();
366#endif /* ! TC_I386 */
367#endif /* ! TC_M68K */
368 }
369 else
370 {
371 words[0] = 0x7ff0;
372 words[1] = 0;
373 words[2] = 0;
374 words[3] = 0;
375 }
376 return return_value;
377 }
378 else if (generic_floating_point_number.sign == 'N')
379 {
380 if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
381 as_warn ("Infinities are not supported by this target\n");
382
383 /* Negative INF. */
384 if (precision == F_PRECISION)
385 {
386 words[0] = 0xff80;
387 words[1] = 0x0;
388 }
389 else if (precision == X_PRECISION)
390 {
391#ifdef TC_M68K
392 words[0] = 0xffff;
393 words[1] = 0;
394 words[2] = 0;
395 words[3] = 0;
396 words[4] = 0;
397 words[5] = 0;
398#else /* ! TC_M68K */
399#ifdef TC_I386
400 words[0] = 0xffff;
401 words[1] = 0x8000;
402 words[2] = 0;
403 words[3] = 0;
404 words[4] = 0;
405#else /* ! TC_I386 */
406 abort ();
407#endif /* ! TC_I386 */
408#endif /* ! TC_M68K */
409 }
410 else
411 {
412 words[0] = 0xfff0;
413 words[1] = 0x0;
414 words[2] = 0x0;
415 words[3] = 0x0;
416 }
417 return return_value;
418 }
419
420 /* The floating point formats we support have:
421 Bit 15 is sign bit.
422 Bits 14:n are excess-whatever exponent.
423 Bits n-1:0 (if any) are most significant bits of fraction.
424 Bits 15:0 of the next word(s) are the next most significant bits.
425
426 So we need: number of bits of exponent, number of bits of
427 mantissa. */
428 bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
429 littlenum_pointer = generic_floating_point_number.leader;
430 littlenums_left = (1
431 + generic_floating_point_number.leader
432 - generic_floating_point_number.low);
433
434 /* Seek (and forget) 1st significant bit. */
435 for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
436 exponent_1 = (generic_floating_point_number.exponent
437 + generic_floating_point_number.leader
438 + 1
439 - generic_floating_point_number.low);
440
441 /* Radix LITTLENUM_RADIX, point just higher than
442 generic_floating_point_number.leader. */
443 exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
444
445 /* Radix 2. */
446 exponent_3 = exponent_2 - exponent_skippage;
447
448 /* Forget leading zeros, forget 1st bit. */
449 exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
450
451 /* Offset exponent. */
452 lp = words;
453
454 /* Word 1. Sign, exponent and perhaps high bits. */
455 word1 = ((generic_floating_point_number.sign == '+')
456 ? 0
457 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
458
459 /* Assume 2's complement integers. */
460 if (exponent_4 <= 0)
461 {
462 int prec_bits;
463 int num_bits;
464
465 unget_bits (1);
466 num_bits = -exponent_4;
467 prec_bits =
468 LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
469#ifdef TC_I386
470 if (precision == X_PRECISION && exponent_bits == 15)
471 {
472 /* On the i386 a denormalized extended precision float is
473 shifted down by one, effectively decreasing the exponent
474 bias by one. */
475 prec_bits -= 1;
476 num_bits += 1;
477 }
478#endif
479
480 if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
481 {
482 /* Bigger than one littlenum. */
483 num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
484 *lp++ = word1;
485 if (num_bits + exponent_bits + 1
486 > precision * LITTLENUM_NUMBER_OF_BITS)
487 {
488 /* Exponent overflow. */
489 make_invalid_floating_point_number (words);
490 return return_value;
491 }
492#ifdef TC_M68K
493 if (precision == X_PRECISION && exponent_bits == 15)
494 *lp++ = 0;
495#endif
496 while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
497 {
498 num_bits -= LITTLENUM_NUMBER_OF_BITS;
499 *lp++ = 0;
500 }
501 if (num_bits)
502 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
503 }
504 else
505 {
506 if (precision == X_PRECISION && exponent_bits == 15)
507 {
508 *lp++ = word1;
509#ifdef TC_M68K
510 *lp++ = 0;
511#endif
512 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
513 }
514 else
515 {
516 word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1)
517 - (exponent_bits + num_bits));
518 *lp++ = word1;
519 }
520 }
521 while (lp < words_end)
522 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
523
524 /* Round the mantissa up, but don't change the number. */
525 if (next_bits (1))
526 {
527 --lp;
528 if (prec_bits >= LITTLENUM_NUMBER_OF_BITS)
529 {
530 int n = 0;
531 int tmp_bits;
532
533 n = 0;
534 tmp_bits = prec_bits;
535 while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
536 {
537 if (lp[n] != (LITTLENUM_TYPE) - 1)
538 break;
539 --n;
540 tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
541 }
542 if (tmp_bits > LITTLENUM_NUMBER_OF_BITS
543 || (lp[n] & mask[tmp_bits]) != mask[tmp_bits]
544 || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS
545 - exponent_bits - 1)
546#ifdef TC_I386
547 /* An extended precision float with only the integer
548 bit set would be invalid. That must be converted
549 to the smallest normalized number. */
550 && !(precision == X_PRECISION
551 && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS
552 - exponent_bits - 2))
553#endif
554 ))
555 {
556 unsigned long carry;
557
558 for (carry = 1; carry && (lp >= words); lp--)
559 {
560 carry = *lp + carry;
561 *lp = carry;
562 carry >>= LITTLENUM_NUMBER_OF_BITS;
563 }
564 }
565 else
566 {
567 /* This is an overflow of the denormal numbers. We
568 need to forget what we have produced, and instead
569 generate the smallest normalized number. */
570 lp = words;
571 word1 = ((generic_floating_point_number.sign == '+')
572 ? 0
573 : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
574 word1 |= (1
575 << ((LITTLENUM_NUMBER_OF_BITS - 1)
576 - exponent_bits));
577 *lp++ = word1;
578#ifdef TC_I386
579 /* Set the integer bit in the extended precision format.
580 This cannot happen on the m68k where the mantissa
581 just overflows into the integer bit above. */
582 if (precision == X_PRECISION)
583 *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
584#endif
585 while (lp < words_end)
586 *lp++ = 0;
587 }
588 }
589 else
590 *lp += 1;
591 }
592
593 return return_value;
594 }
595 else if ((unsigned long) exponent_4 > mask[exponent_bits]
596 || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision)
597 && (unsigned long) exponent_4 == mask[exponent_bits]))
598 {
599 /* Exponent overflow. Lose immediately. */
600
601 /* We leave return_value alone: admit we read the
602 number, but return a floating exception
603 because we can't encode the number. */
604 make_invalid_floating_point_number (words);
605 return return_value;
606 }
607 else
608 {
609 word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
610 | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
611 }
612
613 *lp++ = word1;
614
615 /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
616 middle. Either way, it is then followed by a 1 bit. */
617 if (exponent_bits == 15 && precision == X_PRECISION)
618 {
619#ifdef TC_M68K
620 *lp++ = 0;
621#endif
622 *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
623 | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
624 }
625
626 /* The rest of the words are just mantissa bits. */
627 while (lp < words_end)
628 *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
629
630 if (next_bits (1))
631 {
632 unsigned long carry;
633 /* Since the NEXT bit is a 1, round UP the mantissa.
634 The cunning design of these hidden-1 floats permits
635 us to let the mantissa overflow into the exponent, and
636 it 'does the right thing'. However, we lose if the
637 highest-order bit of the lowest-order word flips.
638 Is that clear? */
639
640 /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
641 Please allow at least 1 more bit in carry than is in a LITTLENUM.
642 We need that extra bit to hold a carry during a LITTLENUM carry
643 propagation. Another extra bit (kept 0) will assure us that we
644 don't get a sticky sign bit after shifting right, and that
645 permits us to propagate the carry without any masking of bits.
646 #endif */
647 for (carry = 1, lp--; carry; lp--)
648 {
649 carry = *lp + carry;
650 *lp = carry;
651 carry >>= LITTLENUM_NUMBER_OF_BITS;
652 if (lp == words)
653 break;
654 }
655 if (precision == X_PRECISION && exponent_bits == 15)
656 {
657 /* Extended precision numbers have an explicit integer bit
658 that we may have to restore. */
659 if (lp == words)
660 {
661#ifdef TC_M68K
662 /* On the m68k there is a gap of 16 bits. We must
663 explicitly propagate the carry into the exponent. */
664 words[0] += words[1];
665 words[1] = 0;
666 lp++;
667#endif
668 /* Put back the integer bit. */
669 lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
670 }
671 }
672 if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
673 {
674 /* We leave return_value alone: admit we read the number,
675 but return a floating exception because we can't encode
676 the number. */
677 *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
678#if 0
679 make_invalid_floating_point_number (words);
680 return return_value;
681#endif
682 }
683 }
684 return return_value;
685}
686
687#if 0
688/* Unused. */
689/* This routine is a real kludge. Someone really should do it better,
690 but I'm too lazy, and I don't understand this stuff all too well
691 anyway. (JF) */
692
693static void
694int_to_gen (x)
695 long x;
696{
697 char buf[20];
698 char *bufp;
699
700 sprintf (buf, "%ld", x);
701 bufp = &buf[0];
702 if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
703 as_bad (_("Error converting number to floating point (Exponent overflow?)"));
704}
705#endif
706
707#ifdef TEST
708char *
709print_gen (gen)
710 FLONUM_TYPE *gen;
711{
712 FLONUM_TYPE f;
713 LITTLENUM_TYPE arr[10];
714 double dv;
715 float fv;
716 static char sbuf[40];
717
718 if (gen)
719 {
720 f = generic_floating_point_number;
721 generic_floating_point_number = *gen;
722 }
723 gen_to_words (&arr[0], 4, 11);
724 memcpy (&dv, &arr[0], sizeof (double));
725 sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv);
726 gen_to_words (&arr[0], 2, 8);
727 memcpy (&fv, &arr[0], sizeof (float));
728 sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
729
730 if (gen)
731 generic_floating_point_number = f;
732
733 return (sbuf);
734}
735
736#endif
Note: See TracBrowser for help on using the repository browser.