aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2025-01-10 08:42:00 +0100
committerJan Beulich <jbeulich@suse.com>2025-01-10 08:42:00 +0100
commit044dd6345f7b275db1ed3b2b9bea7a3e46b1ea09 (patch)
treeab37d865cf05ccf47e3c65708222f3fdd44438f3
parent6f04937e1d7db190ca96ec08d8aeb25f0ec6e994 (diff)
downloadbinutils-044dd6345f7b275db1ed3b2b9bea7a3e46b1ea09.zip
binutils-044dd6345f7b275db1ed3b2b9bea7a3e46b1ea09.tar.gz
binutils-044dd6345f7b275db1ed3b2b9bea7a3e46b1ea09.tar.bz2
gas: make deferred expression evaluation generally latch dot
Deferring expression evaluation is often necessary. However, the value current_location() records typically is intended to represent the location at the point of use of the expression, with the exception being .eqv (or its == equivalent). Change how expr_defer behaves in this regard, and introduce a special mode just for pseudo_set() to use. Introduce a predicate to cover both "deferred" modes, and use it everywhere except in current_location(), where only the new mode wants checking for.
-rw-r--r--gas/config/tc-m32r.c4
-rw-r--r--gas/config/tc-metag.c4
-rw-r--r--gas/config/tc-mn10300.c4
-rw-r--r--gas/config/tc-ppc.c2
-rw-r--r--gas/config/tc-sh.c4
-rw-r--r--gas/expr.c10
-rw-r--r--gas/expr.h5
-rw-r--r--gas/read.c2
8 files changed, 19 insertions, 16 deletions
diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c
index aa0acea..3505b3a 100644
--- a/gas/config/tc-m32r.c
+++ b/gas/config/tc-m32r.c
@@ -2333,13 +2333,13 @@ m32r_parse_name (char const *name,
/* If we have an absolute symbol or a
reg, then we know its value now. */
segment = S_GET_SEGMENT (exprP->X_add_symbol);
- if (mode != expr_defer && segment == absolute_section)
+ if (!expr_defer_p (mode) && segment == absolute_section)
{
exprP->X_op = O_constant;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
exprP->X_add_symbol = NULL;
}
- else if (mode != expr_defer && segment == reg_section)
+ else if (!expr_defer_p (mode) && segment == reg_section)
{
exprP->X_op = O_register;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
diff --git a/gas/config/tc-metag.c b/gas/config/tc-metag.c
index bf084f7..f436435 100644
--- a/gas/config/tc-metag.c
+++ b/gas/config/tc-metag.c
@@ -6908,13 +6908,13 @@ metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode,
/* If we have an absolute symbol or a
reg, then we know its value now. */
segment = S_GET_SEGMENT (exprP->X_add_symbol);
- if (mode != expr_defer && segment == absolute_section)
+ if (!expr_defer_p (mode) && segment == absolute_section)
{
exprP->X_op = O_constant;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
exprP->X_add_symbol = NULL;
}
- else if (mode != expr_defer && segment == reg_section)
+ else if (!expr_defer_p (mode) && segment == reg_section)
{
exprP->X_op = O_register;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c
index 08f6a1c..3fc7cac 100644
--- a/gas/config/tc-mn10300.c
+++ b/gas/config/tc-mn10300.c
@@ -2475,13 +2475,13 @@ mn10300_parse_name (char const *name,
/* If we have an absolute symbol or a reg,
then we know its value now. */
segment = S_GET_SEGMENT (exprP->X_add_symbol);
- if (mode != expr_defer && segment == absolute_section)
+ if (!expr_defer_p (mode) && segment == absolute_section)
{
exprP->X_op = O_constant;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
exprP->X_add_symbol = NULL;
}
- else if (mode != expr_defer && segment == reg_section)
+ else if (!expr_defer_p (mode) && segment == reg_section)
{
exprP->X_op = O_register;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 1ff1175..d1de57e 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -902,7 +902,7 @@ ppc_parse_name (const char *name, expressionS *exp, enum expr_mode mode)
/* If we have an absolute symbol or a reg, then we know its value
now. Copy the symbol value expression to propagate X_md. */
bool done = false;
- if (mode != expr_defer
+ if (!expr_defer_p (mode)
&& !S_FORCE_RELOC (sym, 0))
{
segT segment = S_GET_SEGMENT (sym);
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c
index fe720e7..d1a7c25 100644
--- a/gas/config/tc-sh.c
+++ b/gas/config/tc-sh.c
@@ -3933,13 +3933,13 @@ sh_parse_name (char const *name,
/* If we have an absolute symbol or a reg, then we know its
value now. */
segment = S_GET_SEGMENT (exprP->X_add_symbol);
- if (mode != expr_defer && segment == absolute_section)
+ if (!expr_defer_p (mode) && segment == absolute_section)
{
exprP->X_op = O_constant;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
exprP->X_add_symbol = NULL;
}
- else if (mode != expr_defer && segment == reg_section)
+ else if (!expr_defer_p (mode) && segment == reg_section)
{
exprP->X_op = O_register;
exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
diff --git a/gas/expr.c b/gas/expr.c
index 5e59b7c..ccd8925 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -738,7 +738,7 @@ current_location (expressionS *expressionp, enum expr_mode mode)
else
{
expressionp->X_op = O_symbol;
- if (mode != expr_defer)
+ if (mode != expr_defer_incl_dot)
{
expressionp->X_add_symbol = symbol_temp_new_now ();
#ifdef tc_new_dot_label
@@ -1387,14 +1387,14 @@ operand (expressionS *expressionP, enum expr_mode mode)
/* If we have an absolute symbol or a reg, then we know its
value now. */
segment = S_GET_SEGMENT (symbolP);
- if (mode != expr_defer
+ if (!expr_defer_p (mode)
&& segment == absolute_section
&& !S_FORCE_RELOC (symbolP, 0))
{
expressionP->X_op = O_constant;
expressionP->X_add_number = S_GET_VALUE (symbolP);
}
- else if (mode != expr_defer && segment == reg_section)
+ else if (!expr_defer_p (mode) && segment == reg_section)
{
expressionP->X_op = O_register;
expressionP->X_add_number = S_GET_VALUE (symbolP);
@@ -1438,7 +1438,7 @@ operand (expressionS *expressionP, enum expr_mode mode)
if (expressionP->X_add_symbol)
symbol_mark_used (expressionP->X_add_symbol);
- if (mode != expr_defer)
+ if (!expr_defer_p (mode))
{
expressionP->X_add_symbol
= symbol_clone_if_forward_ref (expressionP->X_add_symbol);
@@ -1933,7 +1933,7 @@ expr (int rankarg, /* Larger # is higher rank. */
is_unsigned = resultP->X_unsigned && right.X_unsigned;
- if (mode == expr_defer
+ if (expr_defer_p (mode)
&& ((resultP->X_add_symbol != NULL
&& S_IS_FORWARD_REF (resultP->X_add_symbol))
|| (right.X_add_symbol != NULL
diff --git a/gas/expr.h b/gas/expr.h
index 351e630..14787c4 100644
--- a/gas/expr.h
+++ b/gas/expr.h
@@ -153,9 +153,12 @@ enum expr_mode
{
expr_evaluate,
expr_normal,
- expr_defer
+ expr_defer,
+ expr_defer_incl_dot,
};
+#define expr_defer_p(m) ((m) >= expr_defer)
+
/* "result" should be type (expressionS *). */
#define expression(result) expr (0, result, expr_normal)
#define expression_and_evaluate(result) expr (0, result, expr_evaluate)
diff --git a/gas/read.c b/gas/read.c
index 5df1f3d..c51536f 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -4069,7 +4069,7 @@ pseudo_set (symbolS *symbolP)
if (!S_IS_FORWARD_REF (symbolP))
(void) expression (&exp);
else
- (void) deferred_expression (&exp);
+ (void) expr (0, &exp, expr_defer_incl_dot);
if (exp.X_op == O_illegal)
as_bad (_("illegal expression"));