/* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64
- Copyright 2009, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
int has_offset; /* 1 if operand has offset. */
unsigned int in_offset; /* >=1 if processing operand of offset. */
unsigned int in_bracket; /* >=1 if processing operand in brackets. */
- unsigned int in_scale; /* >=1 if processing multipication operand
+ unsigned int in_scale; /* >=1 if processing multiplication operand
* in brackets. */
i386_operand_type reloc_types; /* Value obtained from lex_got(). */
const reg_entry *base; /* Base register (if any). */
int adjust = 0;
char *gotfree_input_line = lex_got (&i.reloc[this_operand],
&adjust,
- &intel_state.reloc_types,
- (i.bnd_prefix != NULL
- || add_bnd_prefix));
+ &intel_state.reloc_types);
if (!gotfree_input_line)
break;
for (j = 0; i386_types[j].name; ++j)
if (strcasecmp (i386_types[j].name, name) == 0)
break;
+
if (i386_types[j].name && *pc == ' ')
{
- char *pname = ++input_line_pointer;
- char c = get_symbol_end ();
+ char *pname;
+ char c;
+
+ ++input_line_pointer;
+ c = get_symbol_name (&pname);
if (strcasecmp (pname, "ptr") == 0)
{
+ /* FIXME: What if c == '"' ? */
pname[-1] = *pc;
*pc = c;
if (intel_syntax > 0 || operands != 1)
return i386_types[j].op;
}
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
input_line_pointer = pname - 1;
}
if (this_operand >= 0 && intel_state.in_bracket)
{
expressionS *scale = NULL;
-
- if (intel_state.index)
- --scale;
+ int has_index = (intel_state.index != NULL);
if (!intel_state.in_scale++)
intel_state.scale_factor = 1;
ret = i386_intel_simplify_symbol (e->X_add_symbol);
- if (ret && !scale && intel_state.index)
+ if (ret && !has_index && intel_state.index)
scale = symbol_get_value_expression (e->X_op_symbol);
if (ret)
ret = i386_intel_simplify_symbol (e->X_op_symbol);
- if (ret && !scale && intel_state.index)
+ if (ret && !scale && !has_index && intel_state.index)
scale = symbol_get_value_expression (e->X_add_symbol);
- if (ret && scale && (scale + 1))
+ if (ret && scale)
{
resolve_expression (scale);
if (scale->X_op != O_constant
|| intel_state.is_mem)
{
/* Memory operand. */
+ if (i.mem_operands == 1 && !maybe_adjust_templates ())
+ return 0;
if ((int) i.mem_operands
>= 2 - !current_templates->start->opcode_modifier.isstring)
{
return 0;
}
+ /* Swap base and index in 16-bit memory operands like
+ [si+bx]. Since i386_index_check is also used in AT&T
+ mode we have to do this here. */
+ if (intel_state.base
+ && intel_state.index
+ && intel_state.base->reg_type.bitfield.reg16
+ && intel_state.index->reg_type.bitfield.reg16
+ && intel_state.base->reg_num >= 6
+ && intel_state.index->reg_num < 6)
+ {
+ i.base_reg = intel_state.index;
+ i.index_reg = intel_state.base;
+ }
+ else
+ {
+ i.base_reg = intel_state.base;
+ i.index_reg = intel_state.index;
+ }
+
+ if (i.base_reg || i.index_reg)
+ i.types[this_operand].bitfield.baseindex = 1;
+
expP = &disp_expressions[i.disp_operands];
memcpy (expP, &exp, sizeof(exp));
resolve_expression (expP);
if (expP->X_op != O_constant
|| expP->X_add_number
- || (!intel_state.base
- && !intel_state.index))
+ || !i.types[this_operand].bitfield.baseindex)
{
i.op[this_operand].disps = expP;
i.disp_operands++;
+ i386_addressing_mode ();
+
if (flag_code == CODE_64BIT)
{
i.types[this_operand].bitfield.disp32 = 1;
return 0;
}
- if (intel_state.base || intel_state.index)
- i.types[this_operand].bitfield.baseindex = 1;
-
if (intel_state.seg)
{
- for (;;)
- {
- expP = symbol_get_value_expression (intel_state.seg);
- if (expP->X_op != O_full_ptr)
- break;
- intel_state.seg = expP->X_add_symbol;
- }
+ expP = symbol_get_value_expression (intel_state.seg);
if (expP->X_op != O_register)
{
as_bad (_("segment register name expected"));
}
}
- /* Swap base and index in 16-bit memory operands like
- [si+bx]. Since i386_index_check is also used in AT&T
- mode we have to do that here. */
- if (intel_state.base
- && intel_state.index
- && intel_state.base->reg_type.bitfield.reg16
- && intel_state.index->reg_type.bitfield.reg16
- && intel_state.base->reg_num >= 6
- && intel_state.index->reg_num < 6)
- {
- i.base_reg = intel_state.index;
- i.index_reg = intel_state.base;
- }
- else
- {
- i.base_reg = intel_state.base;
- i.index_reg = intel_state.index;
- }
-
if (!i386_index_check (operand_string))
return 0;
i.types[this_operand].bitfield.mem = 1;
+ if (i.mem_operands == 0)
+ i.memop1_string = xstrdup (operand_string);
++i.mem_operands;
}
else