aboutsummaryrefslogtreecommitdiff
path: root/gas/expr.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2001-09-09 14:01:17 +0000
committerAlan Modra <amodra@gmail.com>2001-09-09 14:01:17 +0000
commite0890092b6a535a9a232ddbed804a0c98a5b4a2c (patch)
treebb42790c1bc434ddffe208d731a1f587e182b9f8 /gas/expr.c
parentf16fbd61d9f5f2940137ea1aea523652964723eb (diff)
downloadgdb-e0890092b6a535a9a232ddbed804a0c98a5b4a2c.zip
gdb-e0890092b6a535a9a232ddbed804a0c98a5b4a2c.tar.gz
gdb-e0890092b6a535a9a232ddbed804a0c98a5b4a2c.tar.bz2
* expr.c (expr): Move code setting "retval" to the end of the loop,
and rearrange for efficiency. For "PIC code" subtraction, use "rightseg" rather than recalculating. For "symbol OP symbol" subtract, set "retval" to absolute_section if symbols in same section. * symbols.c (resolve_symbol_value): Resolve "sym +/- expr" to an O_symbol. Simplify a +/- b code. Allow equality and non-equality comparisons on symbols from any section. Allow other comparison operators as for subtraction. (symbol_equated_reloc_p): New predicate function. * symbols.h (symbol_equated_reloc_p): Declare. * write.c (adjust_reloc_syms): Use symbol_equated_reloc_p. (write_relocs): Likewise. (write_object_file): Likewise. (relax_segment <rs_machine_dependent>): Ensure segment for expression syms is set correctly. * config/tc-mips.c (md_estimate_size_before_relax): Likewise. * config/tc-i386.c (md_assemble <Output jumps>): Don't lose part of a complex expression when setting up frag_var.
Diffstat (limited to 'gas/expr.c')
-rw-r--r--gas/expr.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/gas/expr.c b/gas/expr.c
index 4258868..4f7f225 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -1699,21 +1699,6 @@ expr (rankarg, resultP)
}
}
- if (retval == undefined_section)
- {
- if (SEG_NORMAL (rightseg))
- retval = rightseg;
- }
- else if (! SEG_NORMAL (retval))
- retval = rightseg;
- else if (SEG_NORMAL (rightseg)
- && retval != rightseg
-#ifdef DIFF_EXPR_OK
- && op_left != O_subtract
-#endif
- )
- as_bad (_("operation combines symbols in different segments"));
-
op_right = operator (&op_chars);
know (op_right == O_illegal
@@ -1769,8 +1754,7 @@ expr (rankarg, resultP)
&& resultP->X_op == O_symbol
&& (symbol_get_frag (right.X_add_symbol)
== symbol_get_frag (resultP->X_add_symbol))
- && SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol)))
-
+ && SEG_NORMAL (rightseg))
{
resultP->X_add_number -= right.X_add_number;
resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
@@ -1865,7 +1849,14 @@ expr (rankarg, resultP)
if (op_left == O_add)
resultP->X_add_number += right.X_add_number;
else if (op_left == O_subtract)
- resultP->X_add_number -= right.X_add_number;
+ {
+ resultP->X_add_number -= right.X_add_number;
+ if (retval == rightseg && SEG_NORMAL (retval))
+ {
+ retval = absolute_section;
+ rightseg = absolute_section;
+ }
+ }
}
else
{
@@ -1877,6 +1868,21 @@ expr (rankarg, resultP)
resultP->X_unsigned = 1;
}
+ if (retval != rightseg)
+ {
+ if (! SEG_NORMAL (retval))
+ {
+ if (retval != undefined_section || SEG_NORMAL (rightseg))
+ retval = rightseg;
+ }
+ else if (SEG_NORMAL (rightseg)
+#ifdef DIFF_EXPR_OK
+ && op_left != O_subtract
+#endif
+ )
+ as_bad (_("operation combines symbols in different segments"));
+ }
+
op_left = op_right;
} /* While next operator is >= this rank. */