This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] further equate changes


This patch eliminates some more problems with equates, namely when the
target of the equates are registers, but also in a few cases when the
target is (yet) undefined.

Built and tested on i686-pc-linux-gnu, x86_64-unknown-linux-gnu,
ia64-unknown-linux-gnu, and for a large number of cross targets.

Jan

gas/
2005-11-28  Jan Beulich  <jbeulich@novell.com>

	* symbols.h (snapshot_symbol): First parameter is now pointer
	to pointer to symbolS.
	* symbols.c (snapshot_symbol): Likewise. Store resulting symbol
	there. Use symbol_equated_p.
	* expr.c (resolve_expression): Change first argument to
	snapshot_symbol. Track possibly changed add_symbol consistently
	across function. Resolve more special cases with known result.
	Also update final_val when replacing add_symbol.

gas/testsuite/
2005-11-28  Jan Beulich  <jbeulich@novell.com>

	* gas/all/cond.s: Also check .if works on equates to undefined
	when the expression value can be known without knowing the
	value of the symbol.
	* gas/all/cond.l: Adjust.
	* gas/i386/equ.s: Also check .if works on (equates to)
	registers when the expression value can be known without
	knowing the value of the register.
	* gas/i386/equ.e: Adjuust.

---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/expr.c	2005-11-09
15:40:05.000000000 +0100
+++ 2005-11-24/gas/expr.c	2005-11-28 12:18:53.000000000 +0100
@@ -1913,7 +1913,7 @@ resolve_expression (expressionS *express
 
     case O_symbol:
     case O_symbol_rva:
-      if (!snapshot_symbol (add_symbol, &left, &seg_left,
&frag_left))
+      if (!snapshot_symbol (&add_symbol, &left, &seg_left,
&frag_left))
 	return 0;
 
       break;
@@ -1921,7 +1921,7 @@ resolve_expression (expressionS *express
     case O_uminus:
     case O_bit_not:
     case O_logical_not:
-      if (!snapshot_symbol (add_symbol, &left, &seg_left,
&frag_left))
+      if (!snapshot_symbol (&add_symbol, &left, &seg_left,
&frag_left))
 	return 0;
 
       if (seg_left != absolute_section)
@@ -1955,8 +1955,8 @@ resolve_expression (expressionS *express
     case O_gt:
     case O_logical_and:
     case O_logical_or:
-      if (!snapshot_symbol (add_symbol, &left, &seg_left, &frag_left)
-	  || !snapshot_symbol (op_symbol, &right, &seg_right,
&frag_right))
+      if (!snapshot_symbol (&add_symbol, &left, &seg_left,
&frag_left)
+	  || !snapshot_symbol (&op_symbol, &right, &seg_right,
&frag_right))
 	return 0;
 
       /* Simplify addition or subtraction of a constant by folding
the
@@ -1974,7 +1974,7 @@ resolve_expression (expressionS *express
 	      final_val += left;
 	      left = right;
 	      seg_left = seg_right;
-	      expressionP->X_add_symbol = expressionP->X_op_symbol;
+	      add_symbol = op_symbol;
 	      op = O_symbol;
 	      break;
 	    }
@@ -1991,9 +1991,17 @@ resolve_expression (expressionS *express
 
       /* Equality and non-equality tests are permitted on anything.
 	 Subtraction, and other comparison operators are permitted if
-	 both operands are in the same section.  Otherwise, both
-	 operands must be absolute.  We already handled the case of
-	 addition or subtraction of a constant above.  */
+	 both operands are in the same section.
+	 Shifts by constant zero are permitted on anything.
+	 Multiplies, bit-ors, and bit-ands with constant zero are
+	 permitted on anything.
+	 Multiplies and divides by constant one are permitted on
+	 anything.
+	 Binary operations with both operands being the same register
+	 or undefined symbol are permitted if the result doesn't depend
+	 on the input value.
+	 Otherwise, both operands must be absolute.  We already handled
+	 the case of addition or subtraction of a constant above.  */
       if (!(seg_left == absolute_section
 	       && seg_right == absolute_section)
 	  && !(op == O_eq || op == O_ne)
@@ -2001,10 +2009,64 @@ resolve_expression (expressionS *express
 		|| op == O_lt || op == O_le || op == O_ge || op ==
O_gt)
 	       && seg_left == seg_right
 	       && (finalize_syms || frag_left == frag_right)
-	       && ((seg_left != undefined_section
-		    && seg_left != reg_section)
-		   || add_symbol == op_symbol)))
-	return 0;
+	       && (seg_left != reg_section || left == right)
+	       && (seg_left != undefined_section || add_symbol ==
op_symbol)))
+	{
+	  if ((seg_left == absolute_section && left == 0)
+	      || (seg_right == absolute_section && right == 0))
+	    {
+	      if (op == O_bit_exclusive_or || op == O_bit_inclusive_or)
+		{
+		  if (seg_right != absolute_section || right != 0)
+		    {
+		      seg_left = seg_right;
+		      left = right;
+		      add_symbol = op_symbol;
+		    }
+		  op = O_symbol;
+		  break;
+		}
+	      else if (op == O_left_shift || op == O_right_shift)
+		{
+		  if (seg_left != absolute_section || left != 0)
+		    {
+		      op = O_symbol;
+		      break;
+		    }
+		}
+	      else if (op != O_multiply
+		       && op != O_bit_or_not && op != O_bit_and)
+	        return 0;
+	    }
+	  else if (op == O_multiply
+		   && seg_left == absolute_section && left == 1)
+	    {
+	      seg_left = seg_right;
+	      left = right;
+	      add_symbol = op_symbol;
+	      op = O_symbol;
+	      break;
+	    }
+	  else if ((op == O_multiply || op == O_divide)
+		   && seg_right == absolute_section && right == 1)
+	    {
+	      op = O_symbol;
+	      break;
+	    }
+	  else if (left != right
+		   || ((seg_left != reg_section || seg_right !=
reg_section)
+		       && (seg_left != undefined_section
+			   || seg_right != undefined_section
+			   || add_symbol != op_symbol)))
+	    return 0;
+	  else if (op == O_bit_and || op == O_bit_inclusive_or)
+	    {
+	      op = O_symbol;
+	      break;
+	    }
+	  else if (op != O_bit_exclusive_or && op != O_bit_or_not)
+	    return 0;
+	}
 
       switch (op)
 	{
@@ -2032,8 +2094,7 @@ resolve_expression (expressionS *express
 	  left = (left == right
 		  && seg_left == seg_right
 		  && (finalize_syms || frag_left == frag_right)
-		  && ((seg_left != undefined_section
-		       && seg_left != reg_section)
+		  && (seg_left != undefined_section
 		      || add_symbol == op_symbol)
 		  ? ~ (valueT) 0 : 0);
 	  if (op == O_ne)
@@ -2066,6 +2127,11 @@ resolve_expression (expressionS *express
 	op = O_constant;
       else if (seg_left == reg_section && final_val == 0)
 	op = O_register;
+      else if (add_symbol != expressionP->X_add_symbol)
+	{
+	  final_val += left;
+	  expressionP->X_add_symbol = add_symbol;
+	}
     }
   expressionP->X_op = op;
 
---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/symbols.c	2005-11-16
09:44:49.000000000 +0100
+++ 2005-11-24/gas/symbols.c	2005-11-24 16:57:17.000000000 +0100
@@ -1354,8 +1354,10 @@ resolve_local_symbol_values (void)
    sub-expressions used.  */
 
 int
-snapshot_symbol (symbolS *symbolP, valueT *valueP, segT *segP, fragS
**fragPP)
+snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS
**fragPP)
 {
+  symbolS *symbolP = *symbolPP;
+
   if (LOCAL_SYMBOL_CHECK (symbolP))
     {
       struct local_symbol *locsym = (struct local_symbol *) symbolP;
@@ -1384,10 +1386,7 @@ snapshot_symbol (symbolS *symbolP, value
 	    {
 	    case O_constant:
 	    case O_register:
-	      /* This check wouldn't be needed if pseudo_set() didn't
set
-		 symbols equated to bare symbols to undefined_section. 
*/
-	      if (symbolP->bsym->section != undefined_section
-		  || symbolP->sy_value.X_op != O_symbol)
+	      if (!symbol_equated_p (symbolP))
 		break;
 	      /* Fall thru.  */
 	    case O_symbol:
@@ -1399,6 +1398,7 @@ snapshot_symbol (symbolS *symbolP, value
 	    }
 	}
 
+      *symbolPP = symbolP;
       *valueP = expr.X_add_number;
       *segP = symbolP->bsym->section;
       *fragPP = symbolP->sy_frag;
---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/symbols.h	2005-11-10
10:53:51.000000000 +0100
+++ 2005-11-24/gas/symbols.h	2005-11-24 16:54:58.000000000 +0100
@@ -61,7 +61,7 @@ void symbol_print_statistics (FILE *);
 void symbol_table_insert (symbolS * symbolP);
 valueT resolve_symbol_value (symbolS *);
 void resolve_local_symbol_values (void);
-int snapshot_symbol (symbolS *, valueT *, segT *, fragS **);
+int snapshot_symbol (symbolS **, valueT *, segT *, fragS **);
 
 void print_symbol_value (symbolS *);
 void print_expr (expressionS *);
---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/testsuite/gas/all/cond.l	2005-11-11
13:44:02.000000000 +0100
+++ 2005-11-24/gas/testsuite/gas/all/cond.l	2005-11-24
13:57:09.000000000 +0100
@@ -27,13 +27,32 @@
 [ 	]*[1-9][0-9]*[ 	]+\.comm[ 	]+c,[ 	]*1[ 	]*
 [ 	]*[1-9][0-9]*[ 	]+\.ifndef[ 	]+c[ 	]*
 [ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
-[ 	]*[1-9][0-9]*[ 	]+
-[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+x,[ 	]*y[ 	]*
-[ 	]*[1-9][0-9]*[ 	]+\.ifndef[ 	]+x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+x[ 	]*<>[ 	]*x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+y,[ 	]*x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.ifndef[ 	]+y[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+x[ 	]*<>[ 	]*y[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+z,[ 	]*x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+y[ 	]*<>[ 	]*z[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+a,[ 	]*y[ 	]*\+[ 	]*1[
	]*
+[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+b,[ 	]*z[ 	]*-[ 	]*1[
	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+a[ 	]*==[ 	]*x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+a[ 	]*-[ 	]*1[ 	]*<>[
	]*x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+a[ 	]*<>[ 	]*b[ 	]*\+[
	]*2[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+a[ 	]*-[ 	]*b[ 	]*<>[
	]*2[ 	]*
 [ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
-[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+y,[ 	]*0[ 	]*
-[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+x[ 	]*
-[ 	]*[1-9][0-9]*[ 	]+\.elseif[ 	]+x[ 	]*
+[ 	]*[1-9][0-9]*[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.equiv[ 	]+x,[ 	]*0[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.if[ 	]+y[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+\.elseif[ 	]+y[ 	]*
 [ 	]*[1-9][0-9]*[ 	]+\.endif[ 	]*
 [ 	]*[1-9][0-9]*[ 	]+
 [ 	]*[1-9][0-9]*[ 	]+\.macro[ 	]+m[ 	]+x,[ 	]*y[ 	]*
---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/testsuite/gas/all/cond.s	2005-11-11
13:40:54.000000000 +0100
+++ 2005-11-24/gas/testsuite/gas/all/cond.s	2005-11-24
13:50:46.000000000 +0100
@@ -35,14 +35,40 @@
 	.err
 	.endif
 
-	.equiv	x, y
-	.ifndef x
+	.if	x <> x
 	.err
 	.endif
-	.equiv	y, 0
-	.if	x
+	.equiv	y, x
+	.ifndef	y
 	.err
-	.elseif	x
+	.endif
+	.if	x <> y
+	.err
+	.endif
+	.equiv	z, x
+	.if	y <> z
+	.err
+	.endif
+
+	.equiv	a, y + 1
+	.equiv	b, z - 1
+	.if	a == x
+	.err
+	.endif
+	.if	a - 1 <> x
+	.err
+	.endif
+	.if	a <> b + 2
+	.err
+	.endif
+	.if	a - b <> 2
+	.err
+	.endif
+
+	.equiv	x, 0
+	.if	y
+	.err
+	.elseif	y
 	.err
 	.endif
 
---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/testsuite/gas/i386/equ.e	2005-10-21
15:43:51.000000000 +0200
+++ 2005-11-24/gas/testsuite/gas/i386/equ.e	2005-11-24
15:23:14.000000000 +0100
@@ -1,2 +1,2 @@
 .*: Assembler messages:
-.*:23: Warning: Treating .* as memory reference
+.*:30: Warning: Treating .* as memory reference
---
/home/jbeulich/src/binutils/mainline/2005-11-24/gas/testsuite/gas/i386/equ.s	2005-10-27
15:33:57.000000000 +0200
+++ 2005-11-24/gas/testsuite/gas/i386/equ.s	2005-11-24
16:55:10.000000000 +0100
@@ -16,6 +16,13 @@ _start:
  .equ x, %st(1)
 	fadd	x
 
+ .if r <> %ecx
+ .err
+ .endif
+ .if r == s
+ .err
+ .endif
+
  .intel_syntax noprefix
  .equ r, -2
  .equ s, -2
@@ -33,5 +40,12 @@ _start:
  .equ x, st(7)
 	fadd	x
 
+ .if s <> gs
+ .err
+ .endif
+ .if s == x
+ .err
+ .endif
+
  .equ r, -3
  .equ s, -3

Attachment: binutils-mainline-reg-equate.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]