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