diff options
Diffstat (limited to 'gas/expr.c')
-rw-r--r-- | gas/expr.c | 39 |
1 files changed, 32 insertions, 7 deletions
@@ -298,7 +298,7 @@ integer_constant (int radix, expressionS *expressionP) #define valuesize 32 #endif - if (is_end_of_line[(unsigned char) *input_line_pointer]) + if (is_end_of_stmt (*input_line_pointer)) { expressionP->X_op = O_absent; return; @@ -632,6 +632,7 @@ integer_constant (int radix, expressionS *expressionP) /* Not a small number. */ expressionP->X_op = O_big; expressionP->X_add_number = number; /* Number of littlenums. */ + expressionP->X_unsigned = 1; input_line_pointer--; /* -> char following number. */ } } @@ -707,6 +708,7 @@ mri_char_constant (expressionS *expressionP) { expressionP->X_op = O_big; expressionP->X_add_number = i; + expressionP->X_unsigned = 1; } else { @@ -769,6 +771,16 @@ expr_build_dot (void) return expr_build_uconstant (abs_section_offset); } +/* Copy an expression, preserving X_md. */ + +static void expr_copy (expressionS *dst, const expressionS *src) +{ + unsigned short md = dst->X_md; + + *dst = *src; + dst->X_md = md; +} + #ifndef md_register_arithmetic # define md_register_arithmetic 1 #endif @@ -803,7 +815,7 @@ operand (expressionS *expressionP, enum expr_mode mode) SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ c = *input_line_pointer++; /* input_line_pointer -> past char in c. */ - if (is_end_of_line[(unsigned char) c]) + if (is_end_of_stmt (c)) goto eol; switch (c) @@ -946,7 +958,7 @@ operand (expressionS *expressionP, enum expr_mode mode) /* 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 (!is_end_of_line[(unsigned char) input_line_pointer[1]] + if (!is_end_of_stmt (input_line_pointer[1]) && strchr (FLT_CHARS, 'f') != NULL) { char *cp = input_line_pointer + 1; @@ -1154,6 +1166,8 @@ operand (expressionS *expressionP, enum expr_mode mode) if (generic_bignum[i]) break; } + + expressionP->X_unsigned = 0; } else if (op == O_logical_not) { @@ -1396,8 +1410,17 @@ operand (expressionS *expressionP, enum expr_mode mode) } else if (!expr_defer_p (mode) && segment == reg_section) { - expressionP->X_op = O_register; - expressionP->X_add_number = S_GET_VALUE (symbolP); + if (md_register_arithmetic) + { + expressionP->X_op = O_register; + expressionP->X_add_number = S_GET_VALUE (symbolP); + } + else + { + expr_copy (expressionP, + symbol_get_value_expression (symbolP)); + resolve_register (expressionP); + } } else { @@ -1668,7 +1691,7 @@ operatorf (int *num_chars) c = *input_line_pointer & 0xff; *num_chars = 1; - if (is_end_of_line[c]) + if (is_end_of_stmt (c)) return O_illegal; #ifdef md_operator @@ -2489,6 +2512,8 @@ void resolve_register (expressionS *expP) do { + if (!md_register_arithmetic && e->X_add_number) + break; sym = e->X_add_symbol; acc += e->X_add_number; e = symbol_get_value_expression (sym); @@ -2497,7 +2522,7 @@ void resolve_register (expressionS *expP) if (e->X_op == O_register) { - *expP = *e; + expr_copy (expP, e); expP->X_add_number += acc; } } |