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