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