static INLINE void i386_intel_fold (expressionS *e, symbolS *sym)
{
expressionS *exp = symbol_get_value_expression (sym);
- if (S_GET_SEGMENT (sym) == absolute_section)
+
+ if (S_GET_SEGMENT (sym) == absolute_section
+ || S_GET_SEGMENT (sym) == expr_section)
{
offsetT val = e->X_add_number;
if (!newsym)
return 0;
e->X_op_symbol = newsym;
- if (e->X_add_symbol)
- e->X_op = O_add;
- else
+ if (!e->X_add_symbol)
i386_intel_fold (e, e->X_op_symbol);
+ else if (S_GET_SEGMENT (e->X_add_symbol) == expr_section
+ && (S_GET_SEGMENT (e->X_op_symbol) == absolute_section
+ || S_GET_SEGMENT (e->X_op_symbol) == expr_section)
+ && symbol_get_value_expression (e->X_op_symbol)->X_op
+ == O_constant)
+ {
+ offsetT val
+ = symbol_get_value_expression (e->X_op_symbol)->X_add_number;
+
+ i386_intel_fold (e, e->X_add_symbol);
+ e->X_add_number += val;
+ }
+ else
+ e->X_op = O_add;
break;
case O_offset:
i386_intel_fold (e, e->X_op_symbol);
break;
+ case O_add:
+ if (this_operand >= 0 && intel_state.in_bracket)
+ {
+ expressionS *left = NULL, *right = NULL;
+ segT leftseg = NULL, rightseg = NULL;
+
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ if (newsym)
+ {
+ e->X_add_symbol = newsym;
+
+ if (base != intel_state.base || state_index != intel_state.index)
+ {
+ base = intel_state.base;
+ state_index = intel_state.index;
+ left = symbol_get_value_expression (newsym);
+ resolve_expression (left);
+ leftseg = S_GET_SEGMENT (newsym);
+ }
+ }
+
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ if (newsym)
+ {
+ e->X_op_symbol = newsym;
+
+ if (base != intel_state.base || state_index != intel_state.index)
+ {
+ base = intel_state.base;
+ state_index = intel_state.index;
+ right = symbol_get_value_expression (newsym);
+ resolve_expression (right);
+ rightseg = S_GET_SEGMENT (newsym);
+ }
+ }
+
+ if (left && right
+ && (leftseg == absolute_section || leftseg == expr_section)
+ && left->X_op == O_constant
+ && (rightseg == absolute_section || rightseg == expr_section)
+ && right->X_op == O_constant)
+ {
+ e->X_op = O_constant;
+ e->X_add_number += left->X_add_number + right->X_add_number;
+ e->X_add_symbol = NULL;
+ e->X_op_symbol = NULL;
+ }
+ else if (left
+ && (leftseg == absolute_section || leftseg == expr_section)
+ && left->X_op == O_constant)
+ i386_intel_fold (e, e->X_op_symbol);
+ else if (right
+ && (rightseg == absolute_section || rightseg == expr_section)
+ && right->X_op == O_constant)
+ i386_intel_fold (e, e->X_add_symbol);
+ }
+ goto fallthrough;
+
case O_multiply:
if (this_operand >= 0 && intel_state.in_bracket)
{
- expressionS *scale = NULL;
+ expressionS *scale = NULL, *other = NULL;
int has_index = (intel_state.index != NULL);
if (!intel_state.in_scale++)
e->X_add_symbol = newsym;
if (!has_index && intel_state.index)
- scale = symbol_get_value_expression (e->X_op_symbol);
+ {
+ scale = symbol_get_value_expression (e->X_op_symbol);
+ other = symbol_get_value_expression (e->X_add_symbol);
+ }
newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
}
e->X_op_symbol = newsym;
if (!scale && !has_index && intel_state.index)
- scale = symbol_get_value_expression (e->X_add_symbol);
+ {
+ scale = symbol_get_value_expression (e->X_add_symbol);
+ other = symbol_get_value_expression (e->X_op_symbol);
+ }
}
if (newsym && scale)
{
+ segT seg;
+
resolve_expression (scale);
if (scale->X_op != O_constant
|| intel_state.index->reg_type.bitfield.word)
scale->X_add_number = 0;
intel_state.scale_factor *= scale->X_add_number;
+
+ resolve_expression (other);
+ seg = S_GET_SEGMENT (newsym);
+ if ((seg == absolute_section || seg == expr_section)
+ && other->X_op == O_constant
+ && other->X_add_number == 0)
+ {
+ e->X_op = O_constant;
+ e->X_add_symbol = NULL;
+ e->X_op_symbol = NULL;
+ }
}
--intel_state.in_scale;
if (this_operand >= 0
&& e->X_op == O_symbol
- && !intel_state.in_offset)
+ && !intel_state.has_offset)
{
segT seg = S_GET_SEGMENT (e->X_add_symbol);
--- /dev/null
+#objdump: -dwMintel
+#name: i386 intel-PC-rel
+#notarget: *-*-msdos* *-*-*go32* *-*-bsd* *-*-darwin*
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <\.text>:
+[ ]*[0-9a-f]+: b8 0[15] 00 00 00[ ]+mov[ ]+eax,(0x)?[15]
+[ ]*[0-9a-f]+: b8 0[ae] 00 00 00[ ]+mov[ ]+eax,0x[ae]
+[ ]*[0-9a-f]+: 8d 91 (0c|10) 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x(c|10)\]
+[ ]*[0-9a-f]+: 8d 91 1[6a] 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x1[6a]\]
+[ ]*[0-9a-f]+: 8d 91 (1c|20) 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x(1c|20)\]
+[ ]*[0-9a-f]+: 8d 14 8d (1f|23) 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x(1f|23)\]
+[ ]*[0-9a-f]+: 8d 14 8d 2[6a] 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x2[6a]\]
+[ ]*[0-9a-f]+: 8d 14 8d (2d|31) 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x(2d|31)\]
+[ ]*[0-9a-f]+: 8d 14 8d 3[48] 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x3[48]\]
+[ ]*[0-9a-f]+: 8d 14 8d 3[bf] 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x3[bf]\]
+[ ]*[0-9a-f]+: 8d 91 4[15] 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x4[15]\]
+[ ]*[0-9a-f]+: 8d 91 4[7b] 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x4[7b]\]
+[ ]*[0-9a-f]+: 8d 91 (4d|51) 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x(4d|51)\]
+[ ]*[0-9a-f]+: 8d 91 5[37] 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x5[37]\]
+[ ]*[0-9a-f]+: 8d 91 5[9d] 00 00 00[ ]+lea[ ]+edx,\[ecx\+0x5[9d]\]
+[ ]*[0-9a-f]+: 8d 14 8d 6[04] 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x6[04]\]
+[ ]*[0-9a-f]+: 8d 14 8d 6[7b] 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x6[7b]\]
+[ ]*[0-9a-f]+: 8d 14 8d (6e|72) 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x(6e|72)\]
+[ ]*[0-9a-f]+: 8d 14 8d 7[59] 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x7[59]\]
+[ ]*[0-9a-f]+: 8d 14 8d (7c|80) 00 00 00[ ]+lea[ ]+edx,\[ecx\*4\+0x(7c|80)\]
+[ ]*[0-9a-f]+: 8d 94 31 8[37] 00 00 00[ ]+lea[ ]+edx,\[ecx\+esi\*1\+0x8[37]\]
+[ ]*[0-9a-f]+: 8d 94 b1 8[ae] 00 00 00[ ]+lea[ ]+edx,\[ecx\+esi\*4\+0x8[ae]\]
+[ ]*[0-9a-f]+: 8d 94 b1 9[59] 00 00 00[ ]+lea[ ]+edx,\[ecx\+esi\*4\+0x9[59]\]
+#pass
--- /dev/null
+ .intel_syntax noprefix
+
+ .data
+0: .long 0
+1: .long 0
+
+ .text
+.Lorg:
+ mov eax, 0b - .Lorg
+ mov eax, 1b - .Lorg
+
+ lea edx, 0b - .Lorg[ecx]
+ lea edx, 1b - .Lorg[ecx]
+ lea edx, 0b - .Lorg[ecx][4]
+
+ lea edx, 0b - .Lorg[ecx*4]
+ lea edx, 0b - .Lorg[4*ecx]
+ lea edx, 0b - .Lorg[2*2*ecx]
+ lea edx, 0b - .Lorg[2*ecx*2]
+ lea edx, 0b - .Lorg[ecx*2*2]
+
+ lea edx, [(0b - .Lorg) + ecx]
+ lea edx, [0b - .Lorg + ecx]
+ lea edx, [ecx + (0b - .Lorg)]
+ lea edx, [ecx + 0b - .Lorg]
+ lea edx, [0b + ecx - .Lorg]
+
+ lea edx, [(0b - .Lorg) + ecx*4]
+ lea edx, [0b - .Lorg + ecx*4]
+ lea edx, [ecx*4 + (0b - .Lorg)]
+ lea edx, [ecx*4 + 0b - .Lorg]
+ lea edx, [0b + ecx*4 - .Lorg]
+
+ lea edx, 0b - .Lorg[ecx][esi]
+ lea edx, 0b - .Lorg[ecx][esi*4]
+ lea edx, 0b - .Lorg[ecx][esi*4][4]