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