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