gas: fix hex float parsing from .dcb.? directives
authorJan Beulich <jbeulich@suse.com>
Wed, 16 Jun 2021 06:55:52 +0000 (08:55 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 16 Jun 2021 06:55:52 +0000 (08:55 +0200)
Unlike for .dc.? the parsing here failed to skip the colon before
calling hex_float(). To avoid both variants of parsing going out of sync
again, introduce a helper used by both.

gas/ChangeLog
gas/read.c
gas/testsuite/gas/all/float.s

index ebbf27f0b6635d95c26339f37e6c97141729fb1a..8fa1be88e816a686016d48b5b1e962d3bae09f4d 100644 (file)
@@ -1,3 +1,9 @@
+2021-06-16  Jan Beulich  <jbeulich@suse.com>
+
+       * read.c (parse_one_float): New.
+       (s_float_space, float_cons): Use it.
+       * testsuite/gas/all/float.s: Add .dc.*, .dcb.*, and .ds.* cases.
+
 2021-06-16  Jan Beulich  <jbeulich@suse.com>
 
        * read.c (emit_expr_with_reloc): Adjust overflow check. Drop
index db1011b6392be85939c53842b9fbaacb27f86a72..935b1fa7bde655542a64f1646f951d315c236c59 100644 (file)
@@ -3616,6 +3616,51 @@ s_nops (int ignore ATTRIBUTE_UNUSED)
   *p = val.X_add_number;
 }
 
+static int
+parse_one_float (int float_type, char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT])
+{
+  int length;
+
+  SKIP_WHITESPACE ();
+
+  /* Skip any 0{letter} that may be present.  Don't even check if the
+     letter is legal.  Someone may invent a "z" format and this routine
+     has no use for such information. Lusers beware: you get
+     diagnostics if your input is ill-conditioned.  */
+  if (input_line_pointer[0] == '0'
+      && ISALPHA (input_line_pointer[1]))
+    input_line_pointer += 2;
+
+  /* Accept :xxxx, where the x's are hex digits, for a floating point
+     with the exact digits specified.  */
+  if (input_line_pointer[0] == ':')
+    {
+      ++input_line_pointer;
+      length = hex_float (float_type, temp);
+      if (length < 0)
+       {
+         ignore_rest_of_line ();
+         return length;
+       }
+    }
+  else
+    {
+      const char *err;
+
+      err = md_atof (float_type, temp, &length);
+      know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+      know (err != NULL || length > 0);
+      if (err)
+       {
+         as_bad (_("bad floating literal: %s"), err);
+         ignore_rest_of_line ();
+         return -1;
+       }
+    }
+
+  return length;
+}
+
 /* This is like s_space, but the value is a floating point number with
    the given precision.  This is for the MRI dcb.s pseudo-op and
    friends.  */
@@ -3650,42 +3695,12 @@ s_float_space (int float_type)
 
   ++input_line_pointer;
 
-  SKIP_WHITESPACE ();
-
-  /* Skip any 0{letter} that may be present.  Don't even check if the
-   * letter is legal.  */
-  if (input_line_pointer[0] == '0'
-      && ISALPHA (input_line_pointer[1]))
-    input_line_pointer += 2;
-
-  /* Accept :xxxx, where the x's are hex digits, for a floating point
-     with the exact digits specified.  */
-  if (input_line_pointer[0] == ':')
-    {
-      flen = hex_float (float_type, temp);
-      if (flen < 0)
-       {
-         ignore_rest_of_line ();
-         if (flag_mri)
-           mri_comment_end (stop, stopc);
-         return;
-       }
-    }
-  else
+  flen = parse_one_float (float_type, temp);
+  if (flen < 0)
     {
-      const char *err;
-
-      err = md_atof (float_type, temp, &flen);
-      know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
-      know (err != NULL || flen > 0);
-      if (err)
-       {
-         as_bad (_("bad floating literal: %s"), err);
-         ignore_rest_of_line ();
-         if (flag_mri)
-           mri_comment_end (stop, stopc);
-         return;
-       }
+      if (flag_mri)
+       mri_comment_end (stop, stopc);
+      return;
     }
 
   while (--count >= 0)
@@ -4909,7 +4924,6 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line.  */
 {
   char *p;
   int length;                  /* Number of chars in an object.  */
-  const char *err;             /* Error from scanning floating literal.  */
   char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
 
   if (is_it_end_of_statement ())
@@ -4943,41 +4957,9 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line.  */
 
   do
     {
-      /* input_line_pointer->1st char of a flonum (we hope!).  */
-      SKIP_WHITESPACE ();
-
-      /* Skip any 0{letter} that may be present. Don't even check if the
-        letter is legal. Someone may invent a "z" format and this routine
-        has no use for such information. Lusers beware: you get
-        diagnostics if your input is ill-conditioned.  */
-      if (input_line_pointer[0] == '0'
-         && ISALPHA (input_line_pointer[1]))
-       input_line_pointer += 2;
-
-      /* Accept :xxxx, where the x's are hex digits, for a floating
-        point with the exact digits specified.  */
-      if (input_line_pointer[0] == ':')
-       {
-         ++input_line_pointer;
-         length = hex_float (float_type, temp);
-         if (length < 0)
-           {
-             ignore_rest_of_line ();
-             return;
-           }
-       }
-      else
-       {
-         err = md_atof (float_type, temp, &length);
-         know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
-         know (err != NULL || length > 0);
-         if (err)
-           {
-             as_bad (_("bad floating literal: %s"), err);
-             ignore_rest_of_line ();
-             return;
-           }
-       }
+      length = parse_one_float (float_type, temp);
+      if (length < 0)
+       return;
 
       if (!need_pass_2)
        {
index 902914f4dc81c5e05d11d22495dc1e614085deac..579ca89af37f73b0e9b9b886a05c4d6325f11139 100644 (file)
@@ -4,3 +4,19 @@ foo:   .single 0r1.2345e+06
        .double 0r2.718282
         .double .0000000000000000000001
         .double 1e-22
+
+       .dc.s 1
+       .dc.s 0f:1234
+       .dcb.s 1, 1
+       .dcb.s 1, 0s:4321
+       .ds.s 1, -1
+
+       .dc.d 1
+       .dc.d 0d:1234
+       .dcb.d 1, 1
+       .dcb.d 1, 0r:4321
+       .ds.d 1, -1
+
+       .dc.x 0x:1234
+       .dcb.x 1, 0x:4321
+       .ds.x 1, -1