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