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:
parent
4504a63467
commit
bb32eac5a9
3 changed files with 75 additions and 71 deletions
|
@ -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
|
||||
|
|
124
gas/read.c
124
gas/read.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue