2005-12-22  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-12-22  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: Adjust.
This commit is contained in:
Jan Beulich 2005-12-22 17:05:40 +00:00
parent e5cc6d1129
commit 2e1e12b1f4
9 changed files with 177 additions and 32 deletions

View File

@ -1,3 +1,14 @@
2005-12-22 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.
2005-12-13 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* config/tc-vax.c: Convert to ISO C90 format. Fix formatting and

View File

@ -1913,7 +1913,7 @@ resolve_expression (expressionS *expressionP)
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 *expressionP)
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 *expressionP)
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 *expressionP)
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 *expressionP)
/* 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 *expressionP)
|| 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 *expressionP)
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,9 @@ resolve_expression (expressionS *expressionP)
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;

View File

@ -1355,8 +1355,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;
@ -1385,10 +1387,7 @@ snapshot_symbol (symbolS *symbolP, valueT *valueP, segT *segP, fragS **fragPP)
{
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:
@ -1400,6 +1399,7 @@ snapshot_symbol (symbolS *symbolP, valueT *valueP, segT *segP, fragS **fragPP)
}
}
*symbolPP = symbolP;
*valueP = expr.X_add_number;
*segP = symbolP->bsym->section;
*fragPP = symbolP->sy_frag;

View File

@ -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 *);

View File

@ -1,3 +1,14 @@
2005-12-22 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: Adjust.
2005-12-14 Jan Beulich <jbeulich@novell.com>
* gas/i386/rex.[sd]: New.

View File

@ -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,[ ]*0[ ]*
[ ]*[1-9][0-9]*[ ]+\.if[ ]+x[ ]*
[ ]*[1-9][0-9]*[ ]+\.elseif[ ]+x[ ]*
[ ]*[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]*[ ]*
[ ]*[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[ ]*

View File

@ -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

View File

@ -1,2 +1,2 @@
.*: Assembler messages:
.*:23: Warning: Treating .* as memory reference
.*:30: Warning: Treating .* as memory reference

View File

@ -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