/* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64
- Copyright (C) 2009-2019 Free Software Foundation, Inc.
+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#define O_dword_ptr O_md26
/* qword ptr X_add_symbol */
#define O_qword_ptr O_md25
-/* oword ptr X_add_symbol */
-#define O_oword_ptr O_md24
+/* mmword ptr X_add_symbol */
+#define O_mmword_ptr O_qword_ptr
/* fword ptr X_add_symbol */
-#define O_fword_ptr O_md23
+#define O_fword_ptr O_md24
/* tbyte ptr X_add_symbol */
-#define O_tbyte_ptr O_md22
+#define O_tbyte_ptr O_md23
+/* oword ptr X_add_symbol */
+#define O_oword_ptr O_md22
/* xmmword ptr X_add_symbol */
-#define O_xmmword_ptr O_md21
+#define O_xmmword_ptr O_oword_ptr
/* ymmword ptr X_add_symbol */
-#define O_ymmword_ptr O_md20
+#define O_ymmword_ptr O_md21
/* zmmword ptr X_add_symbol */
-#define O_zmmword_ptr O_md19
+#define O_zmmword_ptr O_md20
static struct
{
I386_TYPE(dword, 4),
I386_TYPE(fword, 6),
I386_TYPE(qword, 8),
+ I386_TYPE(mmword, 8),
I386_TYPE(tbyte, 10),
I386_TYPE(oword, 16),
I386_TYPE(xmmword, 16),
{
unsigned int j;
+#ifdef SVR4_COMMENT_CHARS
+ if (!name && operands == 2 && *input_line_pointer == '\\')
+ switch (input_line_pointer[1])
+ {
+ case '/': input_line_pointer += 2; return O_divide;
+ case '%': input_line_pointer += 2; return O_modulus;
+ case '*': input_line_pointer += 2; return O_multiply;
+ }
+#endif
+
if (!intel_syntax)
return O_absent;
intel_state.base = i386_regtab + reg_num;
else if (!intel_state.index)
{
+ const insn_template *t = current_templates->start;
+
if (intel_state.in_scale
- || current_templates->start->base_opcode == 0xf30f1b /* bndmk */
- || (current_templates->start->base_opcode & ~1) == 0x0f1a /* bnd{ld,st}x */
+ || (t->opcode_modifier.opcodeprefix == PREFIX_0XF3
+ && t->opcode_modifier.opcodespace == SPACE_0F
+ && t->base_opcode == 0x1b /* bndmk */)
+ || (t->opcode_modifier.opcodeprefix == PREFIX_NONE
+ && t->opcode_modifier.opcodespace == SPACE_0F
+ && (t->base_opcode & ~1) == 0x1a /* bnd{ld,st}x */)
|| i386_regtab[reg_num].reg_type.bitfield.baseindex)
intel_state.index = i386_regtab + reg_num;
else
else
{
/* esp is invalid as index */
- intel_state.index = i386_regtab + REGNAM_EAX + ESP_REG_NUM;
+ intel_state.index = reg_eax + ESP_REG_NUM;
}
return 2;
}
case O_word_ptr:
case O_dword_ptr:
case O_fword_ptr:
- case O_qword_ptr:
+ case O_qword_ptr: /* O_mmword_ptr */
case O_tbyte_ptr:
- case O_oword_ptr:
- case O_xmmword_ptr:
+ case O_oword_ptr: /* O_xmmword_ptr */
case O_ymmword_ptr:
case O_zmmword_ptr:
case O_near_ptr:
break;
default:
/* esp is invalid as index */
- intel_state.index = i386_regtab + REGNAM_EAX + ESP_REG_NUM;
+ intel_state.index = reg_eax + ESP_REG_NUM;
break;
}
/* FALLTHROUGH */
default:
-fallthrough:
+ fallthrough:
if (e->X_add_symbol
&& !i386_intel_simplify_symbol (e->X_add_symbol))
return 0;
return 0;
if (intel_state.op_modifier != O_absent
- && current_templates->start->base_opcode != 0x8d /* lea */)
+ && (current_templates->start->opcode_modifier.opcodespace != SPACE_BASE
+ || current_templates->start->base_opcode != 0x8d /* lea */))
{
i.types[this_operand].bitfield.unspecified = 0;
case O_word_ptr:
i.types[this_operand].bitfield.word = 1;
- if ((current_templates->start->name[0] == 'l'
- && current_templates->start->name[2] == 's'
- && current_templates->start->name[3] == 0)
- || current_templates->start->base_opcode == 0x62 /* bound */)
- suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
- else if (got_a_float == 2) /* "fi..." */
+ if (got_a_float == 2) /* "fi..." */
suffix = SHORT_MNEM_SUFFIX;
else
suffix = WORD_MNEM_SUFFIX;
if ((current_templates->start->name[0] == 'l'
&& current_templates->start->name[2] == 's'
&& current_templates->start->name[3] == 0)
- || current_templates->start->base_opcode == 0x62 /* bound */)
+ || (current_templates->start->opcode_modifier.opcodespace == SPACE_BASE
+ && current_templates->start->base_opcode == 0x62 /* bound */))
suffix = WORD_MNEM_SUFFIX;
- else if (flag_code == CODE_16BIT
+ else if (flag_code != CODE_32BIT
&& (current_templates->start->opcode_modifier.jump == JUMP
|| current_templates->start->opcode_modifier.jump
== JUMP_DWORD))
- suffix = LONG_DOUBLE_MNEM_SUFFIX;
+ suffix = flag_code == CODE_16BIT ? LONG_DOUBLE_MNEM_SUFFIX
+ : WORD_MNEM_SUFFIX;
else if (got_a_float == 1) /* "f..." */
suffix = SHORT_MNEM_SUFFIX;
else
add_prefix (DATA_PREFIX_OPCODE);
suffix = LONG_DOUBLE_MNEM_SUFFIX;
}
- else
- suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
break;
- case O_qword_ptr:
+ case O_qword_ptr: /* O_mmword_ptr */
i.types[this_operand].bitfield.qword = 1;
- if (current_templates->start->base_opcode == 0x62 /* bound */
+ if ((current_templates->start->opcode_modifier.opcodespace == SPACE_BASE
+ && current_templates->start->base_opcode == 0x62 /* bound */)
|| got_a_float == 1) /* "f..." */
suffix = LONG_MNEM_SUFFIX;
else
i.types[this_operand].bitfield.tbyte = 1;
if (got_a_float == 1)
suffix = LONG_DOUBLE_MNEM_SUFFIX;
+ else if ((current_templates->start->operand_types[0].bitfield.fword
+ || current_templates->start->operand_types[0].bitfield.tbyte
+ || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+ || current_templates->start->opcode_modifier.jump == JUMP)
+ && flag_code == CODE_64BIT)
+ suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt, call, jmp */
else
- suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
+ i.types[this_operand].bitfield.byte = 1; /* cause an error */
break;
- case O_oword_ptr:
- case O_xmmword_ptr:
+ case O_oword_ptr: /* O_xmmword_ptr */
i.types[this_operand].bitfield.xmmword = 1;
break;
case O_near_ptr:
if (current_templates->start->opcode_modifier.jump != JUMP
&& current_templates->start->opcode_modifier.jump != JUMP_DWORD)
- suffix = got_a_float /* so it will cause an error */
- ? BYTE_MNEM_SUFFIX
- : LONG_DOUBLE_MNEM_SUFFIX;
+ {
+ /* cause an error */
+ i.types[this_operand].bitfield.byte = 1;
+ i.types[this_operand].bitfield.tbyte = 1;
+ suffix = i.suffix;
+ }
break;
default:
|| current_templates->start->opcode_modifier.jump == JUMP_DWORD
|| current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT)
{
- bfd_boolean jumpabsolute = FALSE;
+ bool jumpabsolute = false;
if (i.op[this_operand].regs
|| intel_state.base
|| intel_state.index
|| intel_state.is_mem > 1)
- jumpabsolute = TRUE;
+ jumpabsolute = true;
else
switch (intel_state.op_modifier)
{
case O_near_ptr:
if (intel_state.seg)
- jumpabsolute = TRUE;
+ jumpabsolute = true;
else
intel_state.is_mem = 1;
break;
if (intel_state.op_modifier == O_absent)
{
if (intel_state.is_indirect == 1)
- jumpabsolute = TRUE;
+ jumpabsolute = true;
break;
}
as_bad (_("cannot infer the segment part of the operand"));
return 0;
}
else if (S_GET_SEGMENT (intel_state.seg) == reg_section)
- jumpabsolute = TRUE;
+ jumpabsolute = true;
else
{
i386_operand_type types;
}
break;
default:
- jumpabsolute = TRUE;
+ jumpabsolute = true;
break;
}
if (jumpabsolute)
{
- i.jumpabsolute = TRUE;
+ i.jumpabsolute = true;
intel_state.is_mem |= 1;
}
}
if (flag_code == CODE_64BIT)
{
- i.types[this_operand].bitfield.disp32 = 1;
if (!i.prefix[ADDR_PREFIX])
{
i.types[this_operand].bitfield.disp64 = 1;
i.types[this_operand].bitfield.disp32s = 1;
}
+ else
+ i.types[this_operand].bitfield.disp32 = 1;
}
else if (!i.prefix[ADDR_PREFIX] ^ (flag_code == CODE_16BIT))
i.types[this_operand].bitfield.disp32 = 1;
as_warn (_("redundant segment overrides"));
break;
}
- switch (i386_regtab[expP->X_add_number].reg_num)
- {
- case 0: i.seg[i.mem_operands] = &es; break;
- case 1: i.seg[i.mem_operands] = &cs; break;
- case 2: i.seg[i.mem_operands] = &ss; break;
- case 3: i.seg[i.mem_operands] = &ds; break;
- case 4: i.seg[i.mem_operands] = &fs; break;
- case 5: i.seg[i.mem_operands] = &gs; break;
- case RegFlat: i.seg[i.mem_operands] = NULL; break;
- }
+ if (i386_regtab[expP->X_add_number].reg_num == RegFlat)
+ i.seg[i.mem_operands] = NULL;
+ else
+ i.seg[i.mem_operands] = &i386_regtab[expP->X_add_number];
}
if (!i386_index_check (operand_string))