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