gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gas / atof-generic.c
index 6d6d1955fb2eee1c7f10f1e3a7af781d2d140157..96a12f7462e36572e5785e2af30bfbd403e96b9a 100644 (file)
@@ -1,34 +1,25 @@
 /* atof_generic.c - turn a string of digits into a Flonum
-   Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987-2020 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
-   GAS is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   GAS is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include <ctype.h>
-#include <string.h>
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include "as.h"
-
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else
-#ifdef sparc
-#include <alloca.h>
-#endif
-#endif
+#include "safe-ctype.h"
 
 #ifndef FALSE
 #define FALSE (0)
 #define TRUE  (1)
 #endif
 
+#ifdef TRACE
+static void flonum_print (const FLONUM_TYPE *);
+#endif
+
+#define ASSUME_DECIMAL_MARK_IS_DOT
+
 /***********************************************************************\
  *                                                                     *
  *     Given a string of decimal digits , with optional decimal        *
   */
 
 int
-atof_generic (address_of_string_pointer,
-             string_of_decimal_marks,
-             string_of_decimal_exponent_marks,
-             address_of_generic_floating_point_number)
-     /* return pointer to just AFTER number we read. */
-     char **address_of_string_pointer;
-     /* At most one per number. */
-     const char *string_of_decimal_marks;
-     const char *string_of_decimal_exponent_marks;
-     FLONUM_TYPE *address_of_generic_floating_point_number;
+atof_generic (/* return pointer to just AFTER number we read.  */
+             char **address_of_string_pointer,
+             /* At most one per number.  */
+             const char *string_of_decimal_marks,
+             const char *string_of_decimal_exponent_marks,
+             FLONUM_TYPE *address_of_generic_floating_point_number)
 {
-  int return_value;            /* 0 means OK. */
+  int return_value;            /* 0 means OK.  */
   char *first_digit;
-  /* char *last_digit; JF unused */
-  int number_of_digits_before_decimal;
-  int number_of_digits_after_decimal;
+  unsigned int number_of_digits_before_decimal;
+  unsigned int number_of_digits_after_decimal;
   long decimal_exponent;
-  int number_of_digits_available;
+  unsigned int number_of_digits_available;
   char digits_sign_char;
 
   /*
@@ -107,6 +99,14 @@ atof_generic (address_of_string_pointer,
   char c;
   int seen_significant_digit;
 
+#ifdef ASSUME_DECIMAL_MARK_IS_DOT
+  gas_assert (string_of_decimal_marks[0] == '.'
+         && string_of_decimal_marks[1] == 0);
+#define IS_DECIMAL_MARK(c)     ((c) == '.')
+#else
+#define IS_DECIMAL_MARK(c)     (0 != strchr (string_of_decimal_marks, (c)))
+#endif
+
   first_digit = *address_of_string_pointer;
   c = *first_digit;
 
@@ -118,46 +118,40 @@ atof_generic (address_of_string_pointer,
   else
     digits_sign_char = '+';
 
-  if ((first_digit[0] == 'n' || first_digit[0] == 'N')
-      && (first_digit[1] == 'a' || first_digit[1] == 'A')
-      && (first_digit[2] == 'n' || first_digit[2] == 'N'))
-    {
-      address_of_generic_floating_point_number->sign = 0;
-      address_of_generic_floating_point_number->exponent = 0;
-      address_of_generic_floating_point_number->leader =
-       address_of_generic_floating_point_number->low;
-      *address_of_string_pointer = first_digit + 3;
-      return 0;
-    }
-
-  if ((first_digit[0] == 'i' || first_digit[0] == 'I')
-      && (first_digit[1] == 'n' || first_digit[1] == 'N')
-      && (first_digit[2] == 'f' || first_digit[2] == 'F'))
+  switch (first_digit[0])
     {
-      address_of_generic_floating_point_number->sign =
-       digits_sign_char == '+' ? 'P' : 'N';
-      address_of_generic_floating_point_number->exponent = 0;
-      address_of_generic_floating_point_number->leader =
-       address_of_generic_floating_point_number->low;
-
-      if ((first_digit[3] == 'i'
-          || first_digit[3] == 'I')
-         && (first_digit[4] == 'n'
-             || first_digit[4] == 'N')
-         && (first_digit[5] == 'i'
-             || first_digit[5] == 'I')
-         && (first_digit[6] == 't'
-             || first_digit[6] == 'T')
-         && (first_digit[7] == 'y'
-             || first_digit[7] == 'Y'))
+    case 'n':
+    case 'N':
+      if (!strncasecmp ("nan", first_digit, 3))
        {
-         *address_of_string_pointer = first_digit + 8;
+         address_of_generic_floating_point_number->sign = 0;
+         address_of_generic_floating_point_number->exponent = 0;
+         address_of_generic_floating_point_number->leader =
+           address_of_generic_floating_point_number->low;
+         *address_of_string_pointer = first_digit + 3;
+         return 0;
        }
-      else
+      break;
+
+    case 'i':
+    case 'I':
+      if (!strncasecmp ("inf", first_digit, 3))
        {
-         *address_of_string_pointer = first_digit + 3;
+         address_of_generic_floating_point_number->sign =
+           digits_sign_char == '+' ? 'P' : 'N';
+         address_of_generic_floating_point_number->exponent = 0;
+         address_of_generic_floating_point_number->leader =
+           address_of_generic_floating_point_number->low;
+
+         first_digit += 3;
+         if (!strncasecmp ("inity", first_digit, 5))
+           first_digit += 5;
+
+         *address_of_string_pointer = first_digit;
+
+         return 0;
        }
-      return 0;
+      break;
     }
 
   number_of_digits_before_decimal = 0;
@@ -166,11 +160,11 @@ atof_generic (address_of_string_pointer,
   seen_significant_digit = 0;
   for (p = first_digit;
        (((c = *p) != '\0')
-       && (!c || !strchr (string_of_decimal_marks, c))
+       && (!c || !IS_DECIMAL_MARK (c))
        && (!c || !strchr (string_of_decimal_exponent_marks, c)));
        p++)
     {
-      if (isdigit (c))
+      if (ISDIGIT (c))
        {
          if (seen_significant_digit || c > '0')
            {
@@ -184,45 +178,64 @@ atof_generic (address_of_string_pointer,
        }
       else
        {
-         break;                /* p -> char after pre-decimal digits. */
+         break;                /* p -> char after pre-decimal digits.  */
        }
-    }                          /* For each digit before decimal mark. */
+    }                          /* For each digit before decimal mark.  */
 
 #ifndef OLD_FLOAT_READS
   /* Ignore trailing 0's after the decimal point.  The original code here
-   * (ifdef'd out) does not do this, and numbers like
-   *   4.29496729600000000000e+09      (2**31)
-   * come out inexact for some reason related to length of the digit
-   * string.
-   */
-  if (c && strchr (string_of_decimal_marks, c))
+     (ifdef'd out) does not do this, and numbers like
+       4.29496729600000000000e+09      (2**31)
+     come out inexact for some reason related to length of the digit
+     string.  */
+
+  /* The case number_of_digits_before_decimal = 0 is handled for
+     deleting zeros after decimal.  In this case the decimal mark and
+     the first zero digits after decimal mark are skipped.  */
+  seen_significant_digit = 0;
+  signed long subtract_decimal_exponent = 0;
+
+  if (c && IS_DECIMAL_MARK (c))
     {
-      int zeros = 0;           /* Length of current string of zeros */
+      unsigned int zeros = 0;  /* Length of current string of zeros.  */
 
-      for (p++; (c = *p) && isdigit (c); p++)
+      if (number_of_digits_before_decimal == 0)
+       /* Skip decimal mark.  */
+       first_digit++;
+
+      for (p++; (c = *p) && ISDIGIT (c); p++)
        {
          if (c == '0')
            {
-             zeros++;
+             if (number_of_digits_before_decimal == 0
+                 && !seen_significant_digit)
+               {
+                 /* Skip '0' and the decimal mark.  */
+                 first_digit++;
+                 subtract_decimal_exponent--;
+               }
+             else
+               zeros++;
            }
          else
            {
+             seen_significant_digit = 1;
              number_of_digits_after_decimal += 1 + zeros;
              zeros = 0;
            }
        }
     }
 #else
-  if (c && strchr (string_of_decimal_marks, c))
+  if (c && IS_DECIMAL_MARK (c))
     {
       for (p++;
           (((c = *p) != '\0')
            && (!c || !strchr (string_of_decimal_exponent_marks, c)));
           p++)
        {
-         if (isdigit (c))
+         if (ISDIGIT (c))
            {
-             /* This may be retracted below. */
+             /* This may be retracted below.  */
              number_of_digits_after_decimal++;
 
              if ( /* seen_significant_digit || */ c > '0')
@@ -238,7 +251,7 @@ atof_generic (address_of_string_pointer,
                }
              break;
            }
-       }                       /* For each digit after decimal mark. */
+       }                       /* For each digit after decimal mark.  */
     }
 
   while (number_of_digits_after_decimal
@@ -247,11 +260,21 @@ atof_generic (address_of_string_pointer,
     --number_of_digits_after_decimal;
 #endif
 
+  if (flag_m68k_mri)
+    {
+      while (c == '_')
+       c = *++p;
+    }
   if (c && strchr (string_of_decimal_exponent_marks, c))
     {
       char digits_exponent_sign_char;
 
       c = *++p;
+      if (flag_m68k_mri)
+       {
+         while (c == '_')
+           c = *++p;
+       }
       if (c && strchr ("+-", c))
        {
          digits_exponent_sign_char = c;
@@ -264,7 +287,7 @@ atof_generic (address_of_string_pointer,
 
       for (; (c); c = *++p)
        {
-         if (isdigit (c))
+         if (ISDIGIT (c))
            {
              decimal_exponent = decimal_exponent * 10 + c - '0';
              /*
@@ -283,9 +306,13 @@ atof_generic (address_of_string_pointer,
        }
     }
 
-  *address_of_string_pointer = p;
-
+#ifndef OLD_FLOAT_READS
+  /* Subtract_decimal_exponent != 0 when number_of_digits_before_decimal = 0
+     and first digit after decimal is '0'.  */
+  decimal_exponent += subtract_decimal_exponent;
+#endif
 
+  *address_of_string_pointer = p;
 
   number_of_digits_available =
     number_of_digits_before_decimal + number_of_digits_after_decimal;
@@ -301,8 +328,10 @@ atof_generic (address_of_string_pointer,
     }
   else
     {
-      int count;               /* Number of useful digits left to scan. */
+      int count;               /* Number of useful digits left to scan.  */
 
+      LITTLENUM_TYPE *temporary_binary_low = NULL;
+      LITTLENUM_TYPE *power_binary_low = NULL;
       LITTLENUM_TYPE *digits_binary_low;
       unsigned int precision;
       unsigned int maximum_useful_digits;
@@ -316,22 +345,14 @@ atof_generic (address_of_string_pointer,
 
       precision = (address_of_generic_floating_point_number->high
                   - address_of_generic_floating_point_number->low
-                  + 1);        /* Number of destination littlenums. */
-
-      /* Includes guard bits (two littlenums worth) */
-#if 0 /* The integer version below is very close, and it doesn't
-        require floating point support (which is currently buggy on
-        the Alpha).  */
-      maximum_useful_digits = (((double) (precision - 2))
-                              * ((double) (LITTLENUM_NUMBER_OF_BITS))
-                              / (LOG_TO_BASE_2_OF_10))
-       + 2;                    /* 2 :: guard digits. */
-#else
-      maximum_useful_digits = (((precision - 2))
-                              * ( (LITTLENUM_NUMBER_OF_BITS))
-                              * 1000000 / 3321928)
-       + 2;                    /* 2 :: guard digits. */
-#endif
+                  + 1);        /* Number of destination littlenums.  */
+
+      /* precision includes two littlenums worth of guard bits,
+        so this gives us 10 decimal guard digits here.  */
+      maximum_useful_digits = (precision
+                              * LITTLENUM_NUMBER_OF_BITS
+                              * 1000000 / 3321928
+                              + 1);    /* round up.  */
 
       if (number_of_digits_available > maximum_useful_digits)
        {
@@ -349,7 +370,7 @@ atof_generic (address_of_string_pointer,
                           - (long) number_of_digits_to_use);
 
       more_than_enough_bits_for_digits
-       = ((((double) number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);
+       = (number_of_digits_to_use * 3321928 / 1000000 + 1);
 
       more_than_enough_littlenums_for_digits
        = (more_than_enough_bits_for_digits
@@ -369,11 +390,11 @@ atof_generic (address_of_string_pointer,
        * sizeof (LITTLENUM_TYPE);
 
       digits_binary_low = (LITTLENUM_TYPE *)
-       alloca (size_of_digits_in_chars);
+       xmalloc (size_of_digits_in_chars);
 
       memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
 
-      /* Digits_binary_low[] is allocated and zeroed. */
+      /* Digits_binary_low[] is allocated and zeroed.  */
 
       /*
        * Parse the decimal digits as if * digits_low was in the units position.
@@ -386,7 +407,7 @@ atof_generic (address_of_string_pointer,
       for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
        {
          c = *p;
-         if (isdigit (c))
+         if (ISDIGIT (c))
            {
              /*
               * Multiply by 10. Assume can never overflow.
@@ -420,16 +441,15 @@ atof_generic (address_of_string_pointer,
                   * We have a GROSS internal error.
                   * This should never happen.
                   */
-                 as_fatal ("failed sanity check.");
+                 as_fatal (_("failed sanity check"));
                }
            }
          else
            {
-             ++count;          /* '.' doesn't alter digits used count. */
+             ++count;          /* '.' doesn't alter digits used count.  */
            }
        }
 
-
       /*
        * Digits_binary_low[] properly encodes the value of the digits.
        * Forget about any high-order littlenums that are 0.
@@ -458,23 +478,21 @@ atof_generic (address_of_string_pointer,
 
       {
        /*
-        * Compute the mantssa (& exponent) of the power of 10.
-        * If sucessful, then multiply the power of 10 by the digits
+        * Compute the mantissa (& exponent) of the power of 10.
+        * If successful, then multiply the power of 10 by the digits
         * giving return_binary_mantissa and return_binary_exponent.
         */
 
-       LITTLENUM_TYPE *power_binary_low;
        int decimal_exponent_is_negative;
-       /* This refers to the "-56" in "12.34E-56". */
+       /* This refers to the "-56" in "12.34E-56".  */
        /* FALSE: decimal_exponent is positive (or 0) */
        /* TRUE:  decimal_exponent is negative */
        FLONUM_TYPE temporary_flonum;
-       LITTLENUM_TYPE *temporary_binary_low;
        unsigned int size_of_power_in_littlenums;
        unsigned int size_of_power_in_chars;
 
        size_of_power_in_littlenums = precision;
-       /* Precision has a built-in fudge factor so we get a few guard bits. */
+       /* Precision has a built-in fudge factor so we get a few guard bits.  */
 
        decimal_exponent_is_negative = decimal_exponent < 0;
        if (decimal_exponent_is_negative)
@@ -482,13 +500,14 @@ atof_generic (address_of_string_pointer,
            decimal_exponent = -decimal_exponent;
          }
 
-       /* From now on: the decimal exponent is > 0. Its sign is seperate. */
+       /* From now on: the decimal exponent is > 0. Its sign is separate.  */
 
        size_of_power_in_chars = size_of_power_in_littlenums
          * sizeof (LITTLENUM_TYPE) + 2;
 
-       power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
-       temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
+       power_binary_low = (LITTLENUM_TYPE *) xmalloc (size_of_power_in_chars);
+       temporary_binary_low = (LITTLENUM_TYPE *) xmalloc (size_of_power_in_chars);
+
        memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
        *power_binary_low = 1;
        power_of_10_flonum.exponent = 0;
@@ -515,7 +534,7 @@ atof_generic (address_of_string_pointer,
          int place_number_limit;
          /* Any 10^(2^n) whose "n" exceeds this */
          /* value will fall off the end of */
-         /* flonum_XXXX_powers_of_ten[]. */
+         /* flonum_XXXX_powers_of_ten[].  */
          int place_number;
          const FLONUM_TYPE *multiplicand;      /* -> 10^(2^n) */
 
@@ -525,8 +544,8 @@ atof_generic (address_of_string_pointer,
                          ? flonum_negative_powers_of_ten
                          : flonum_positive_powers_of_ten);
 
-         for (place_number = 1;/* Place value of this bit of exponent. */
-              decimal_exponent;/* Quit when no more 1 bits in exponent. */
+         for (place_number = 1;/* Place value of this bit of exponent.  */
+              decimal_exponent;/* Quit when no more 1 bits in exponent.  */
               decimal_exponent >>= 1, place_number++)
            {
              if (decimal_exponent & 1)
@@ -534,11 +553,11 @@ atof_generic (address_of_string_pointer,
                  if (place_number > place_number_limit)
                    {
                      /* The decimal exponent has a magnitude so great
-                        that our tables can't help us fragment it.
-                        Although this routine is in error because it
-                        can't imagine a number that big, signal an
-                        error as if it is the user's fault for
-                        presenting such a big number.  */
+                        that our tables can't help us fragment it.
+                        Although this routine is in error because it
+                        can't imagine a number that big, signal an
+                        error as if it is the user's fault for
+                        presenting such a big number.  */
                      return_value = ERROR_EXPONENT_OVERFLOW;
                      /* quit out of loop gracefully */
                      decimal_exponent = 0;
@@ -551,20 +570,34 @@ atof_generic (address_of_string_pointer,
 
                      flonum_print (&power_of_10_flonum);
                      (void) putchar ('\n');
+#endif
+#ifdef TRACE
+                     printf ("multiplier:\n");
+                     flonum_print (multiplicand + place_number);
+                     (void) putchar ('\n');
 #endif
                      flonum_multip (multiplicand + place_number,
                                     &power_of_10_flonum, &temporary_flonum);
+#ifdef TRACE
+                     printf ("after multiply:\n");
+                     flonum_print (&temporary_flonum);
+                     (void) putchar ('\n');
+#endif
                      flonum_copy (&temporary_flonum, &power_of_10_flonum);
+#ifdef TRACE
+                     printf ("after copy:\n");
+                     flonum_print (&power_of_10_flonum);
+                     (void) putchar ('\n');
+#endif
                    } /* If this bit of decimal_exponent was computable.*/
-               } /* If this bit of decimal_exponent was set. */
+               } /* If this bit of decimal_exponent was set.  */
            } /* For each bit of binary representation of exponent */
 #ifdef TRACE
-         printf (" after computing power_of_10_flonum: ");
+         printf ("after computing power_of_10_flonum:\n");
          flonum_print (&power_of_10_flonum);
          (void) putchar ('\n');
 #endif
        }
-
       }
 
       /*
@@ -575,11 +608,35 @@ atof_generic (address_of_string_pointer,
        */
 
       flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
-      /* Assert sign of the number we made is '+'. */
+      /* Assert sign of the number we made is '+'.  */
       address_of_generic_floating_point_number->sign = digits_sign_char;
 
+      free (temporary_binary_low);
+      free (power_binary_low);
+      free (digits_binary_low);
     }
   return return_value;
 }
 
+#ifdef TRACE
+static void
+flonum_print (f)
+     const FLONUM_TYPE *f;
+{
+  LITTLENUM_TYPE *lp;
+  char littlenum_format[10];
+  sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
+#define print_littlenum(LP)    (printf (littlenum_format, LP))
+  printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
+  if (f->low < f->high)
+    for (lp = f->high; lp >= f->low; lp--)
+      print_littlenum (*lp);
+  else
+    for (lp = f->low; lp <= f->high; lp++)
+      print_littlenum (*lp);
+  printf ("\n");
+  fflush (stdout);
+}
+#endif
+
 /* end of atof_generic.c */
This page took 0.031103 seconds and 4 git commands to generate.