diff options
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/expr.c | 92 | ||||
-rw-r--r-- | gas/symbols.c | 10 | ||||
-rw-r--r-- | gas/symbols.h | 2 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/all/cond.l | 31 | ||||
-rw-r--r-- | gas/testsuite/gas/all/cond.s | 36 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/equ.e | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/equ.s | 14 |
9 files changed, 177 insertions, 32 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 3e0af99..6172e07 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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 @@ -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; diff --git a/gas/symbols.c b/gas/symbols.c index 8e3d492..c9298e0 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -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; diff --git a/gas/symbols.h b/gas/symbols.h index d4e56fb..7a4b8f7 100644 --- a/gas/symbols.h +++ b/gas/symbols.h @@ -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 *); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index a7e9c9f..41a06b3 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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. diff --git a/gas/testsuite/gas/all/cond.l b/gas/testsuite/gas/all/cond.l index 6939ee8..36f0066 100644 --- a/gas/testsuite/gas/all/cond.l +++ b/gas/testsuite/gas/all/cond.l @@ -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[ ]* diff --git a/gas/testsuite/gas/all/cond.s b/gas/testsuite/gas/all/cond.s index 94136ac..164e055 100644 --- a/gas/testsuite/gas/all/cond.s +++ b/gas/testsuite/gas/all/cond.s @@ -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 diff --git a/gas/testsuite/gas/i386/equ.e b/gas/testsuite/gas/i386/equ.e index b91d71c..8a485d1 100644 --- a/gas/testsuite/gas/i386/equ.e +++ b/gas/testsuite/gas/i386/equ.e @@ -1,2 +1,2 @@ .*: Assembler messages: -.*:23: Warning: Treating .* as memory reference +.*:30: Warning: Treating .* as memory reference diff --git a/gas/testsuite/gas/i386/equ.s b/gas/testsuite/gas/i386/equ.s index 792c46a..1b7a796 100644 --- a/gas/testsuite/gas/i386/equ.s +++ b/gas/testsuite/gas/i386/equ.s @@ -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 |