return 2;
}
-static int
-i386_intel_simplify_symbol (symbolS *sym)
+static symbolS *
+i386_intel_simplify_symbol (symbolS *sym, bool in_equate)
{
if (symbol_resolving_p (sym))
- return 1;
+ return sym;
- symbol_mark_resolving (sym);
- int ret = i386_intel_simplify (symbol_get_value_expression (sym));
- if (ret == 2)
+ segT seg = S_GET_SEGMENT (sym);
+ if (seg != expr_section && seg != reg_section && !symbol_equated_p(sym))
+ return sym;
+
+ for (;;)
{
- S_SET_SEGMENT (sym, absolute_section);
- ret = 1;
+ /* While we're after equates, symbol_equated_p() isn't suitable here. */
+ if (symbol_on_chain(sym, symbol_rootP, symbol_lastP))
+ {
+ in_equate = true;
+ sym = symbol_clone (sym, 0);
+ }
+ else if (in_equate)
+ {
+ expressionS *e = symbol_get_value_expression (sym);
+
+ if (e->X_op == O_symbol && !e->X_add_number)
+ {
+ sym = e->X_add_symbol;
+ continue;
+ }
+ sym = make_expr_symbol (e);
+ }
+
+ break;
}
+
+ symbol_mark_resolving (sym);
+ int ret = i386_intel_simplify (symbol_get_value_expression (sym), in_equate);
+ if (ret == 2)
+ S_SET_SEGMENT (sym, absolute_section);
symbol_clear_resolving (sym);
- return ret;
+
+ return ret ? sym : NULL;
}
static int
-i386_intel_simplify (expressionS *e)
+i386_intel_simplify (expressionS *e, bool in_equate)
{
const reg_entry *the_reg = (this_operand >= 0
? i.op[this_operand].regs : NULL);
const reg_entry *base = intel_state.base;
const reg_entry *state_index = intel_state.index;
+ symbolS *newsym;
int ret;
if (!intel_syntax)
case O_index:
if (e->X_add_symbol)
{
- if (!i386_intel_simplify_symbol (e->X_add_symbol)
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ if (!newsym
|| !i386_intel_check(the_reg, intel_state.base,
intel_state.index))
return 0;
+ e->X_add_symbol = newsym;
}
if (!intel_state.in_offset)
++intel_state.in_bracket;
- ret = i386_intel_simplify_symbol (e->X_op_symbol);
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
if (!intel_state.in_offset)
--intel_state.in_bracket;
- if (!ret)
+ if (!newsym)
return 0;
+ e->X_op_symbol = newsym;
if (e->X_add_symbol)
e->X_op = O_add;
else
case O_offset:
intel_state.has_offset = 1;
++intel_state.in_offset;
- ret = i386_intel_simplify_symbol (e->X_add_symbol);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
--intel_state.in_offset;
- if (!ret || !i386_intel_check(the_reg, base, state_index))
+ if (!newsym || !i386_intel_check(the_reg, base, state_index))
return 0;
+ e->X_add_symbol = newsym;
i386_intel_fold (e, e->X_add_symbol);
- return ret;
+ return 1;
case O_byte_ptr:
case O_word_ptr:
as_bad (_("invalid use of register"));
return 0;
}
- if (!i386_intel_simplify_symbol (e->X_add_symbol))
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ if (!newsym)
return 0;
+ e->X_add_symbol = newsym;
i386_intel_fold (e, e->X_add_symbol);
break;
as_bad (_("invalid use of register"));
return 0;
}
- if (!i386_intel_simplify_symbol (e->X_op_symbol)
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ if (!newsym
|| !i386_intel_check(the_reg, intel_state.base,
intel_state.index))
return 0;
+ e->X_op_symbol = newsym;
if (!intel_state.in_offset)
{
if (!intel_state.seg)
if (!intel_state.in_scale++)
intel_state.scale_factor = 1;
- ret = i386_intel_simplify_symbol (e->X_add_symbol);
- if (ret && !has_index && intel_state.index)
- scale = symbol_get_value_expression (e->X_op_symbol);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ if (newsym)
+ {
+ e->X_add_symbol = newsym;
- if (ret)
- ret = i386_intel_simplify_symbol (e->X_op_symbol);
- if (ret && !scale && !has_index && intel_state.index)
- scale = symbol_get_value_expression (e->X_add_symbol);
+ if (!has_index && intel_state.index)
+ scale = symbol_get_value_expression (e->X_op_symbol);
+
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ }
+
+ if (newsym)
+ {
+ e->X_op_symbol = newsym;
+
+ if (!scale && !has_index && intel_state.index)
+ scale = symbol_get_value_expression (e->X_add_symbol);
+ }
- if (ret && scale)
+ if (newsym && scale)
{
resolve_expression (scale);
if (scale->X_op != O_constant
}
--intel_state.in_scale;
- if (!ret)
+ if (!newsym)
return 0;
if (!intel_state.in_scale)
/* FALLTHROUGH */
default:
fallthrough:
- if (e->X_add_symbol
- && !i386_intel_simplify_symbol (e->X_add_symbol))
- return 0;
+ if (e->X_add_symbol)
+ {
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ if (!newsym)
+ return 0;
+ e->X_add_symbol = newsym;
+ }
if (!the_reg && this_operand >= 0
&& e->X_op == O_symbol && !e->X_add_number)
the_reg = i.op[this_operand].regs;
base = intel_state.base;
state_index = intel_state.index;
}
- if (!i386_intel_check (the_reg, base, state_index)
- || (e->X_op_symbol
- && !i386_intel_simplify_symbol (e->X_op_symbol))
- || !i386_intel_check (the_reg,
- (e->X_op != O_add
- ? base : intel_state.base),
- (e->X_op != O_add
- ? state_index : intel_state.index)))
+ if (!i386_intel_check (the_reg, base, state_index))
+ return 0;
+ if (e->X_op_symbol)
+ {
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ if (!newsym)
+ return 0;
+ e->X_op_symbol = newsym;
+ }
+ if (!i386_intel_check (the_reg,
+ e->X_op != O_add ? base : intel_state.base,
+ (e->X_op != O_add ? state_index
+ : intel_state.index)))
return 0;
break;
}
expr_mode = expr_operator_none;
memset (&exp, 0, sizeof(exp));
exp_seg = expression (&exp);
- ret = i386_intel_simplify (&exp);
+ ret = i386_intel_simplify (&exp, false);
intel_syntax = 1;
SKIP_WHITESPACE ();