aboutsummaryrefslogtreecommitdiff
path: root/gas/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/expr.c')
-rw-r--r--gas/expr.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/gas/expr.c b/gas/expr.c
index b22346e..78a247c 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -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;
}
}