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