* 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.
This commit is contained in:
Alan Modra 2001-09-09 14:01:17 +00:00
parent f16fbd61d9
commit e0890092b6
7 changed files with 174 additions and 76 deletions

View file

@ -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. */