2004-03-05 H.J. Lu <hongjiu.lu@intel.com>
[external/binutils.git] / gas / atof-generic.c
1 /* atof_generic.c - turn a string of digits into a Flonum
2    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 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 <string.h>
23
24 #include "as.h"
25 #include "safe-ctype.h"
26
27 #ifndef FALSE
28 #define FALSE (0)
29 #endif
30 #ifndef TRUE
31 #define TRUE  (1)
32 #endif
33
34 #ifdef TRACE
35 static void flonum_print (const FLONUM_TYPE *);
36 #endif
37
38 #define ASSUME_DECIMAL_MARK_IS_DOT
39
40 /***********************************************************************\
41  *                                                                      *
42  *      Given a string of decimal digits , with optional decimal        *
43  *      mark and optional decimal exponent (place value) of the         *
44  *      lowest_order decimal digit: produce a floating point            *
45  *      number. The number is 'generic' floating point: our             *
46  *      caller will encode it for a specific machine architecture.      *
47  *                                                                      *
48  *      Assumptions                                                     *
49  *              uses base (radix) 2                                     *
50  *              this machine uses 2's complement binary integers        *
51  *              target flonums use "      "         "       "           *
52  *              target flonums exponents fit in a long                  *
53  *                                                                      *
54  \***********************************************************************/
55
56 /*
57
58   Syntax:
59
60   <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
61   <optional-sign> ::= '+' | '-' | {empty}
62   <decimal-number> ::= <integer>
63   | <integer> <radix-character>
64   | <integer> <radix-character> <integer>
65   | <radix-character> <integer>
66
67   <optional-exponent> ::= {empty}
68   | <exponent-character> <optional-sign> <integer>
69
70   <integer> ::= <digit> | <digit> <integer>
71   <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
72   <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
73   <radix-character> ::= {one character from "string_of_decimal_marks"}
74
75   */
76
77 int
78 atof_generic (/* return pointer to just AFTER number we read.  */
79               char **address_of_string_pointer,
80               /* At most one per number.  */
81               const char *string_of_decimal_marks,
82               const char *string_of_decimal_exponent_marks,
83               FLONUM_TYPE *address_of_generic_floating_point_number)
84 {
85   int return_value;             /* 0 means OK.  */
86   char *first_digit;
87   unsigned int number_of_digits_before_decimal;
88   unsigned int number_of_digits_after_decimal;
89   long decimal_exponent;
90   unsigned int number_of_digits_available;
91   char digits_sign_char;
92
93   /*
94    * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
95    * It would be simpler to modify the string, but we don't; just to be nice
96    * to caller.
97    * We need to know how many digits we have, so we can allocate space for
98    * the digits' value.
99    */
100
101   char *p;
102   char c;
103   int seen_significant_digit;
104
105 #ifdef ASSUME_DECIMAL_MARK_IS_DOT
106   assert (string_of_decimal_marks[0] == '.'
107           && string_of_decimal_marks[1] == 0);
108 #define IS_DECIMAL_MARK(c)      ((c) == '.')
109 #else
110 #define IS_DECIMAL_MARK(c)      (0 != strchr (string_of_decimal_marks, (c)))
111 #endif
112
113   first_digit = *address_of_string_pointer;
114   c = *first_digit;
115
116   if (c == '-' || c == '+')
117     {
118       digits_sign_char = c;
119       first_digit++;
120     }
121   else
122     digits_sign_char = '+';
123
124   switch (first_digit[0])
125     {
126     case 'n':
127     case 'N':
128       if (!strncasecmp ("nan", first_digit, 3))
129         {
130           address_of_generic_floating_point_number->sign = 0;
131           address_of_generic_floating_point_number->exponent = 0;
132           address_of_generic_floating_point_number->leader =
133             address_of_generic_floating_point_number->low;
134           *address_of_string_pointer = first_digit + 3;
135           return 0;
136         }
137       break;
138
139     case 'i':
140     case 'I':
141       if (!strncasecmp ("inf", first_digit, 3))
142         {
143           address_of_generic_floating_point_number->sign =
144             digits_sign_char == '+' ? 'P' : 'N';
145           address_of_generic_floating_point_number->exponent = 0;
146           address_of_generic_floating_point_number->leader =
147             address_of_generic_floating_point_number->low;
148
149           first_digit += 3;
150           if (!strncasecmp ("inity", first_digit, 5))
151             first_digit += 5;
152
153           *address_of_string_pointer = first_digit;
154
155           return 0;
156         }
157       break;
158     }
159
160   number_of_digits_before_decimal = 0;
161   number_of_digits_after_decimal = 0;
162   decimal_exponent = 0;
163   seen_significant_digit = 0;
164   for (p = first_digit;
165        (((c = *p) != '\0')
166         && (!c || !IS_DECIMAL_MARK (c))
167         && (!c || !strchr (string_of_decimal_exponent_marks, c)));
168        p++)
169     {
170       if (ISDIGIT (c))
171         {
172           if (seen_significant_digit || c > '0')
173             {
174               ++number_of_digits_before_decimal;
175               seen_significant_digit = 1;
176             }
177           else
178             {
179               first_digit++;
180             }
181         }
182       else
183         {
184           break;                /* p -> char after pre-decimal digits.  */
185         }
186     }                           /* For each digit before decimal mark.  */
187
188 #ifndef OLD_FLOAT_READS
189   /* Ignore trailing 0's after the decimal point.  The original code here
190    * (ifdef'd out) does not do this, and numbers like
191    *    4.29496729600000000000e+09      (2**31)
192    * come out inexact for some reason related to length of the digit
193    * string.
194    */
195   if (c && IS_DECIMAL_MARK (c))
196     {
197       unsigned int zeros = 0;   /* Length of current string of zeros */
198
199       for (p++; (c = *p) && ISDIGIT (c); p++)
200         {
201           if (c == '0')
202             {
203               zeros++;
204             }
205           else
206             {
207               number_of_digits_after_decimal += 1 + zeros;
208               zeros = 0;
209             }
210         }
211     }
212 #else
213   if (c && IS_DECIMAL_MARK (c))
214     {
215       for (p++;
216            (((c = *p) != '\0')
217             && (!c || !strchr (string_of_decimal_exponent_marks, c)));
218            p++)
219         {
220           if (ISDIGIT (c))
221             {
222               /* This may be retracted below.  */
223               number_of_digits_after_decimal++;
224
225               if ( /* seen_significant_digit || */ c > '0')
226                 {
227                   seen_significant_digit = TRUE;
228                 }
229             }
230           else
231             {
232               if (!seen_significant_digit)
233                 {
234                   number_of_digits_after_decimal = 0;
235                 }
236               break;
237             }
238         }                       /* For each digit after decimal mark.  */
239     }
240
241   while (number_of_digits_after_decimal
242          && first_digit[number_of_digits_before_decimal
243                         + number_of_digits_after_decimal] == '0')
244     --number_of_digits_after_decimal;
245 #endif
246
247   if (flag_m68k_mri)
248     {
249       while (c == '_')
250         c = *++p;
251     }
252   if (c && strchr (string_of_decimal_exponent_marks, c))
253     {
254       char digits_exponent_sign_char;
255
256       c = *++p;
257       if (flag_m68k_mri)
258         {
259           while (c == '_')
260             c = *++p;
261         }
262       if (c && strchr ("+-", c))
263         {
264           digits_exponent_sign_char = c;
265           c = *++p;
266         }
267       else
268         {
269           digits_exponent_sign_char = '+';
270         }
271
272       for (; (c); c = *++p)
273         {
274           if (ISDIGIT (c))
275             {
276               decimal_exponent = decimal_exponent * 10 + c - '0';
277               /*
278                * BUG! If we overflow here, we lose!
279                */
280             }
281           else
282             {
283               break;
284             }
285         }
286
287       if (digits_exponent_sign_char == '-')
288         {
289           decimal_exponent = -decimal_exponent;
290         }
291     }
292
293   *address_of_string_pointer = p;
294
295   number_of_digits_available =
296     number_of_digits_before_decimal + number_of_digits_after_decimal;
297   return_value = 0;
298   if (number_of_digits_available == 0)
299     {
300       address_of_generic_floating_point_number->exponent = 0;   /* Not strictly necessary */
301       address_of_generic_floating_point_number->leader
302         = -1 + address_of_generic_floating_point_number->low;
303       address_of_generic_floating_point_number->sign = digits_sign_char;
304       /* We have just concocted (+/-)0.0E0 */
305
306     }
307   else
308     {
309       int count;                /* Number of useful digits left to scan.  */
310
311       LITTLENUM_TYPE *digits_binary_low;
312       unsigned int precision;
313       unsigned int maximum_useful_digits;
314       unsigned int number_of_digits_to_use;
315       unsigned int more_than_enough_bits_for_digits;
316       unsigned int more_than_enough_littlenums_for_digits;
317       unsigned int size_of_digits_in_littlenums;
318       unsigned int size_of_digits_in_chars;
319       FLONUM_TYPE power_of_10_flonum;
320       FLONUM_TYPE digits_flonum;
321
322       precision = (address_of_generic_floating_point_number->high
323                    - address_of_generic_floating_point_number->low
324                    + 1);        /* Number of destination littlenums.  */
325
326       /* Includes guard bits (two littlenums worth) */
327 #if 0 /* The integer version below is very close, and it doesn't
328          require floating point support (which is currently buggy on
329          the Alpha).  */
330       maximum_useful_digits = (((double) (precision - 2))
331                                * ((double) (LITTLENUM_NUMBER_OF_BITS))
332                                / (LOG_TO_BASE_2_OF_10))
333         + 2;                    /* 2 :: guard digits.  */
334 #else
335       maximum_useful_digits = (((precision - 2))
336                                * ( (LITTLENUM_NUMBER_OF_BITS))
337                                * 1000000 / 3321928)
338         + 2;                    /* 2 :: guard digits.  */
339 #endif
340
341       if (number_of_digits_available > maximum_useful_digits)
342         {
343           number_of_digits_to_use = maximum_useful_digits;
344         }
345       else
346         {
347           number_of_digits_to_use = number_of_digits_available;
348         }
349
350       /* Cast these to SIGNED LONG first, otherwise, on systems with
351          LONG wider than INT (such as Alpha OSF/1), unsignedness may
352          cause unexpected results.  */
353       decimal_exponent += ((long) number_of_digits_before_decimal
354                            - (long) number_of_digits_to_use);
355
356 #if 0
357       more_than_enough_bits_for_digits
358         = ((((double) number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);
359 #else
360       more_than_enough_bits_for_digits
361         = (number_of_digits_to_use * 3321928 / 1000000 + 1);
362 #endif
363
364       more_than_enough_littlenums_for_digits
365         = (more_than_enough_bits_for_digits
366            / LITTLENUM_NUMBER_OF_BITS)
367         + 2;
368
369       /* Compute (digits) part. In "12.34E56" this is the "1234" part.
370          Arithmetic is exact here. If no digits are supplied then this
371          part is a 0 valued binary integer.  Allocate room to build up
372          the binary number as littlenums.  We want this memory to
373          disappear when we leave this function.  Assume no alignment
374          problems => (room for n objects) == n * (room for 1
375          object).  */
376
377       size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
378       size_of_digits_in_chars = size_of_digits_in_littlenums
379         * sizeof (LITTLENUM_TYPE);
380
381       digits_binary_low = (LITTLENUM_TYPE *)
382         alloca (size_of_digits_in_chars);
383
384       memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
385
386       /* Digits_binary_low[] is allocated and zeroed.  */
387
388       /*
389        * Parse the decimal digits as if * digits_low was in the units position.
390        * Emit a binary number into digits_binary_low[].
391        *
392        * Use a large-precision version of:
393        * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
394        */
395
396       for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
397         {
398           c = *p;
399           if (ISDIGIT (c))
400             {
401               /*
402                * Multiply by 10. Assume can never overflow.
403                * Add this digit to digits_binary_low[].
404                */
405
406               long carry;
407               LITTLENUM_TYPE *littlenum_pointer;
408               LITTLENUM_TYPE *littlenum_limit;
409
410               littlenum_limit = digits_binary_low
411                 + more_than_enough_littlenums_for_digits
412                 - 1;
413
414               carry = c - '0';  /* char -> binary */
415
416               for (littlenum_pointer = digits_binary_low;
417                    littlenum_pointer <= littlenum_limit;
418                    littlenum_pointer++)
419                 {
420                   long work;
421
422                   work = carry + 10 * (long) (*littlenum_pointer);
423                   *littlenum_pointer = work & LITTLENUM_MASK;
424                   carry = work >> LITTLENUM_NUMBER_OF_BITS;
425                 }
426
427               if (carry != 0)
428                 {
429                   /*
430                    * We have a GROSS internal error.
431                    * This should never happen.
432                    */
433                   as_fatal (_("failed sanity check"));
434                 }
435             }
436           else
437             {
438               ++count;          /* '.' doesn't alter digits used count.  */
439             }
440         }
441
442       /*
443        * Digits_binary_low[] properly encodes the value of the digits.
444        * Forget about any high-order littlenums that are 0.
445        */
446       while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
447              && size_of_digits_in_littlenums >= 2)
448         size_of_digits_in_littlenums--;
449
450       digits_flonum.low = digits_binary_low;
451       digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
452       digits_flonum.leader = digits_flonum.high;
453       digits_flonum.exponent = 0;
454       /*
455        * The value of digits_flonum . sign should not be important.
456        * We have already decided the output's sign.
457        * We trust that the sign won't influence the other parts of the number!
458        * So we give it a value for these reasons:
459        * (1) courtesy to humans reading/debugging
460        *     these numbers so they don't get excited about strange values
461        * (2) in future there may be more meaning attached to sign,
462        *     and what was
463        *     harmless noise may become disruptive, ill-conditioned (or worse)
464        *     input.
465        */
466       digits_flonum.sign = '+';
467
468       {
469         /*
470          * Compute the mantssa (& exponent) of the power of 10.
471          * If successful, then multiply the power of 10 by the digits
472          * giving return_binary_mantissa and return_binary_exponent.
473          */
474
475         LITTLENUM_TYPE *power_binary_low;
476         int decimal_exponent_is_negative;
477         /* This refers to the "-56" in "12.34E-56".  */
478         /* FALSE: decimal_exponent is positive (or 0) */
479         /* TRUE:  decimal_exponent is negative */
480         FLONUM_TYPE temporary_flonum;
481         LITTLENUM_TYPE *temporary_binary_low;
482         unsigned int size_of_power_in_littlenums;
483         unsigned int size_of_power_in_chars;
484
485         size_of_power_in_littlenums = precision;
486         /* Precision has a built-in fudge factor so we get a few guard bits.  */
487
488         decimal_exponent_is_negative = decimal_exponent < 0;
489         if (decimal_exponent_is_negative)
490           {
491             decimal_exponent = -decimal_exponent;
492           }
493
494         /* From now on: the decimal exponent is > 0. Its sign is separate.  */
495
496         size_of_power_in_chars = size_of_power_in_littlenums
497           * sizeof (LITTLENUM_TYPE) + 2;
498
499         power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
500         temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
501         memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
502         *power_binary_low = 1;
503         power_of_10_flonum.exponent = 0;
504         power_of_10_flonum.low = power_binary_low;
505         power_of_10_flonum.leader = power_binary_low;
506         power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
507         power_of_10_flonum.sign = '+';
508         temporary_flonum.low = temporary_binary_low;
509         temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
510         /*
511          * (power) == 1.
512          * Space for temporary_flonum allocated.
513          */
514
515         /*
516          * ...
517          *
518          * WHILE        more bits
519          * DO   find next bit (with place value)
520          *      multiply into power mantissa
521          * OD
522          */
523         {
524           int place_number_limit;
525           /* Any 10^(2^n) whose "n" exceeds this */
526           /* value will fall off the end of */
527           /* flonum_XXXX_powers_of_ten[].  */
528           int place_number;
529           const FLONUM_TYPE *multiplicand;      /* -> 10^(2^n) */
530
531           place_number_limit = table_size_of_flonum_powers_of_ten;
532
533           multiplicand = (decimal_exponent_is_negative
534                           ? flonum_negative_powers_of_ten
535                           : flonum_positive_powers_of_ten);
536
537           for (place_number = 1;/* Place value of this bit of exponent.  */
538                decimal_exponent;/* Quit when no more 1 bits in exponent.  */
539                decimal_exponent >>= 1, place_number++)
540             {
541               if (decimal_exponent & 1)
542                 {
543                   if (place_number > place_number_limit)
544                     {
545                       /* The decimal exponent has a magnitude so great
546                          that our tables can't help us fragment it.
547                          Although this routine is in error because it
548                          can't imagine a number that big, signal an
549                          error as if it is the user's fault for
550                          presenting such a big number.  */
551                       return_value = ERROR_EXPONENT_OVERFLOW;
552                       /* quit out of loop gracefully */
553                       decimal_exponent = 0;
554                     }
555                   else
556                     {
557 #ifdef TRACE
558                       printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
559                               place_number);
560
561                       flonum_print (&power_of_10_flonum);
562                       (void) putchar ('\n');
563 #endif
564 #ifdef TRACE
565                       printf ("multiplier:\n");
566                       flonum_print (multiplicand + place_number);
567                       (void) putchar ('\n');
568 #endif
569                       flonum_multip (multiplicand + place_number,
570                                      &power_of_10_flonum, &temporary_flonum);
571 #ifdef TRACE
572                       printf ("after multiply:\n");
573                       flonum_print (&temporary_flonum);
574                       (void) putchar ('\n');
575 #endif
576                       flonum_copy (&temporary_flonum, &power_of_10_flonum);
577 #ifdef TRACE
578                       printf ("after copy:\n");
579                       flonum_print (&power_of_10_flonum);
580                       (void) putchar ('\n');
581 #endif
582                     } /* If this bit of decimal_exponent was computable.*/
583                 } /* If this bit of decimal_exponent was set.  */
584             } /* For each bit of binary representation of exponent */
585 #ifdef TRACE
586           printf ("after computing power_of_10_flonum:\n");
587           flonum_print (&power_of_10_flonum);
588           (void) putchar ('\n');
589 #endif
590         }
591
592       }
593
594       /*
595        * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
596        * It may be the number 1, in which case we don't NEED to multiply.
597        *
598        * Multiply (decimal digits) by power_of_10_flonum.
599        */
600
601       flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
602       /* Assert sign of the number we made is '+'.  */
603       address_of_generic_floating_point_number->sign = digits_sign_char;
604
605     }
606   return return_value;
607 }
608
609 #ifdef TRACE
610 static void
611 flonum_print (f)
612      const FLONUM_TYPE *f;
613 {
614   LITTLENUM_TYPE *lp;
615   char littlenum_format[10];
616   sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
617 #define print_littlenum(LP)     (printf (littlenum_format, LP))
618   printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
619   if (f->low < f->high)
620     for (lp = f->high; lp >= f->low; lp--)
621       print_littlenum (*lp);
622   else
623     for (lp = f->low; lp <= f->high; lp++)
624       print_littlenum (*lp);
625   printf ("\n");
626   fflush (stdout);
627 }
628 #endif
629
630 /* end of atof_generic.c */