/* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64
- Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 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),
else
reg_num = e->X_md - 1;
+ if (reg_num < 0 || reg_num >= (int) i386_regtab_size)
+ {
+ as_bad (_("invalid register number"));
+ return 0;
+ }
+
if (!intel_state.in_bracket)
{
if (i.op[this_operand].regs)
as_bad (_("invalid use of register"));
return 0;
}
- if (i386_regtab[reg_num].reg_type.bitfield.sreg3
+ if (i386_regtab[reg_num].reg_type.bitfield.class == SReg
&& i386_regtab[reg_num].reg_num == RegFlat)
{
as_bad (_("invalid use of pseudo-register"));
&& (i386_regtab[reg_num].reg_type.bitfield.xmmword
|| i386_regtab[reg_num].reg_type.bitfield.ymmword
|| i386_regtab[reg_num].reg_type.bitfield.zmmword
- || i386_regtab[reg_num].reg_num == RegRiz
- || i386_regtab[reg_num].reg_num == RegEiz))
+ || i386_regtab[reg_num].reg_num == RegIZ))
intel_state.index = i386_regtab + reg_num;
else if (!intel_state.base && !intel_state.in_scale)
intel_state.base = i386_regtab + reg_num;
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:
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;
&& current_templates->start->name[3] == 0)
|| current_templates->start->base_opcode == 0x62 /* bound */)
suffix = WORD_MNEM_SUFFIX;
- else if (flag_code == CODE_16BIT
- && (current_templates->start->opcode_modifier.jump
- || current_templates->start->opcode_modifier.jumpdword))
- suffix = LONG_DOUBLE_MNEM_SUFFIX;
+ else if (flag_code != CODE_32BIT
+ && (current_templates->start->opcode_modifier.jump == JUMP
+ || current_templates->start->opcode_modifier.jump
+ == JUMP_DWORD))
+ 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 */
|| got_a_float == 1) /* "f..." */
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;
- suffix = XMMWORD_MNEM_SUFFIX;
break;
case O_ymmword_ptr:
i.types[this_operand].bitfield.ymmword = 1;
- suffix = YMMWORD_MNEM_SUFFIX;
break;
case O_zmmword_ptr:
i.types[this_operand].bitfield.zmmword = 1;
- suffix = ZMMWORD_MNEM_SUFFIX;
break;
case O_far_ptr:
suffix = LONG_DOUBLE_MNEM_SUFFIX;
/* FALLTHROUGH */
case O_near_ptr:
- if (!current_templates->start->opcode_modifier.jump
- && !current_templates->start->opcode_modifier.jumpdword)
- suffix = got_a_float /* so it will cause an error */
- ? BYTE_MNEM_SUFFIX
- : LONG_DOUBLE_MNEM_SUFFIX;
+ if (current_templates->start->opcode_modifier.jump != JUMP
+ && current_templates->start->opcode_modifier.jump != JUMP_DWORD)
+ {
+ /* cause an error */
+ i.types[this_operand].bitfield.byte = 1;
+ i.types[this_operand].bitfield.tbyte = 1;
+ suffix = i.suffix;
+ }
break;
default:
}
/* Operands for jump/call need special consideration. */
- if (current_templates->start->opcode_modifier.jump
- || current_templates->start->opcode_modifier.jumpdword
- || current_templates->start->opcode_modifier.jumpintersegment)
+ if (current_templates->start->opcode_modifier.jump == JUMP
+ || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+ || current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT)
{
+ bfd_boolean jumpabsolute = FALSE;
+
if (i.op[this_operand].regs
|| intel_state.base
|| intel_state.index
|| intel_state.is_mem > 1)
- i.types[this_operand].bitfield.jumpabsolute = 1;
+ jumpabsolute = TRUE;
else
switch (intel_state.op_modifier)
{
case O_near_ptr:
if (intel_state.seg)
- i.types[this_operand].bitfield.jumpabsolute = 1;
+ jumpabsolute = TRUE;
else
intel_state.is_mem = 1;
break;
if (intel_state.op_modifier == O_absent)
{
if (intel_state.is_indirect == 1)
- i.types[this_operand].bitfield.jumpabsolute = 1;
+ 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)
- i.types[this_operand].bitfield.jumpabsolute = 1;
+ jumpabsolute = TRUE;
else
{
i386_operand_type types;
}
break;
default:
- i.types[this_operand].bitfield.jumpabsolute = 1;
+ jumpabsolute = TRUE;
break;
}
- if (i.types[this_operand].bitfield.jumpabsolute)
- intel_state.is_mem |= 1;
+ if (jumpabsolute)
+ {
+ i.jumpabsolute = TRUE;
+ intel_state.is_mem |= 1;
+ }
}
else if (intel_state.seg)
intel_state.is_mem |= 1;
ljmp 0x9090,0x90909090
*/
- if ((current_templates->start->opcode_modifier.jumpintersegment
- || current_templates->start->opcode_modifier.jumpdword
- || current_templates->start->opcode_modifier.jump)
+ if ((current_templates->start->opcode_modifier.jump == JUMP_INTERSEGMENT
+ || current_templates->start->opcode_modifier.jump == JUMP_DWORD
+ || current_templates->start->opcode_modifier.jump == JUMP)
&& this_operand == 1
&& intel_state.seg == NULL
&& i.mem_operands == 1
i.mem_operands = 0;
i.disp_operands = 0;
i.imm_operands = 2;
- i.types[0].bitfield.mem = 0;
+ i.flags[0] &= ~Operand_Mem;
i.types[0].bitfield.disp16 = 0;
i.types[0].bitfield.disp32 = 0;
i.types[0].bitfield.disp32s = 0;
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_bad (_("segment register name expected"));
return 0;
}
- if (!i386_regtab[expP->X_add_number].reg_type.bitfield.sreg2
- && !i386_regtab[expP->X_add_number].reg_type.bitfield.sreg3)
+ if (i386_regtab[expP->X_add_number].reg_type.bitfield.class != SReg)
{
as_bad (_("invalid use of register"));
return 0;
if (!i386_index_check (operand_string))
return 0;
- i.types[this_operand].bitfield.mem = 1;
+ i.flags[this_operand] |= Operand_Mem;
if (i.mem_operands == 0)
i.memop1_string = xstrdup (operand_string);
++i.mem_operands;