diff options
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/expr.c | 63 |
2 files changed, 30 insertions, 38 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 9fa7032..ecf77fb 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,4 +1,9 @@ 2015-08-13 Alan Modra <amodra@gmail.com> + + * expr.c (operand): Rewrite handling of operands starting with "0f". + If atof_generic only parses "-" or "+", treat as expression. + +2015-08-13 Alan Modra <amodra@gmail.com> DJ Delorie <dj@redhat.com> * expr.c (integer_constant): Return O_absent expression if eol. @@ -877,48 +877,35 @@ operand (expressionS *expressionP, enum expr_mode mode) case 'f': if (LOCAL_LABELS_FB) { + int is_label = 1; + /* If it says "0f" and it could possibly be a floating point number, make it one. Otherwise, make it a local label, and try to deal with parsing the rest later. */ - if (!input_line_pointer[1] - || (is_end_of_line[0xff & input_line_pointer[1]]) - || strchr (FLT_CHARS, 'f') == NULL) - goto is_0f_label; - { - char *cp = input_line_pointer + 1; - int r = atof_generic (&cp, ".", EXP_CHARS, - &generic_floating_point_number); - switch (r) - { - case 0: - case ERROR_EXPONENT_OVERFLOW: - if (*cp == 'f' || *cp == 'b') - /* Looks like a difference expression. */ - goto is_0f_label; - else if (cp == input_line_pointer + 1) - /* No characters has been accepted -- looks like - end of operand. */ - goto is_0f_label; - else - goto is_0f_float; - default: - as_fatal (_("expr.c(operand): bad atof_generic return val %d"), - r); - } - } - - /* Okay, now we've sorted it out. We resume at one of these - two labels, depending on what we've decided we're probably - looking at. */ - is_0f_label: - input_line_pointer--; - integer_constant (10, expressionP); - break; - - is_0f_float: - /* Fall through. */ - ; + if (!is_end_of_line[(unsigned char) input_line_pointer[1]] + && strchr (FLT_CHARS, 'f') != NULL) + { + char *cp = input_line_pointer + 1; + + atof_generic (&cp, ".", EXP_CHARS, + &generic_floating_point_number); + + /* Was nothing parsed, or does it look like an + expression? */ + is_label = (cp == input_line_pointer + 1 + || (cp == input_line_pointer + 2 + && (cp[-1] == '-' || cp[-1] == '+')) + || *cp == 'f' + || *cp == 'b'); + } + if (is_label) + { + input_line_pointer--; + integer_constant (10, expressionP); + break; + } } + /* Fall through. */ case 'd': case 'D': |