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