[v2,1/3] gas: make deferred expression evaluation generally latch dot

Message ID af5c7d52-9ee5-4064-90ca-5ca71fdb2c3e@suse.com
State New
Headers
Series gas: dot handling |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Jan Beulich Dec. 19, 2024, 10:07 a.m. UTC
  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.
---
v2: Make expr_defer be the mode where . is latched, special casing just
    forward equates in pseudo_set().
  

Patch

--- a/gas/config/tc-m32r.c
+++ b/gas/config/tc-m32r.c
@@ -2335,13 +2335,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);
--- a/gas/config/tc-metag.c
+++ b/gas/config/tc-metag.c
@@ -6908,13 +6908,13 @@  metag_parse_name (char const * name, exp
       /* 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);
--- a/gas/config/tc-mn10300.c
+++ b/gas/config/tc-mn10300.c
@@ -2478,13 +2478,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);
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -902,7 +902,7 @@  ppc_parse_name (const char *name, expres
   /* 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);
--- 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);
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -738,7 +738,7 @@  current_location (expressionS *expressio
   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
 	  /* 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
   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 highe
 
       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
--- 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)
--- a/gas/read.c
+++ b/gas/read.c
@@ -4068,7 +4068,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"));