gas: fix hex float parsing from .dcb.? directives

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.
This commit is contained in:
Jan Beulich 2021-06-16 08:55:52 +02:00
parent 4504a63467
commit bb32eac5a9
3 changed files with 75 additions and 71 deletions

View 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

View 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 = parse_one_float (float_type, temp);
if (flen < 0)
{
flen = hex_float (float_type, temp);
if (flen < 0)
{
ignore_rest_of_line ();
if (flag_mri)
mri_comment_end (stop, stopc);
return;
}
}
else
{
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)
{

View 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