enum
{
vex_encoding_default = 0,
- vex_encoding_vex2,
+ vex_encoding_vex,
vex_encoding_vex3,
vex_encoding_evex
} vec_encoding;
unsigned int j;
if (optimize_for_space
+ && !is_any_vex_encoding (&i.tm)
&& i.reg_operands == 1
&& i.imm_operands == 1
&& !i.types[1].bitfield.byte
&& i.op[0].imms->X_op == O_constant
&& fits_in_imm7 (i.op[0].imms->X_add_number)
- && ((i.tm.base_opcode == 0xa8
- && i.tm.extension_opcode == None)
+ && (i.tm.base_opcode == 0xa8
|| (i.tm.base_opcode == 0xf6
&& i.tm.extension_opcode == 0x0)))
{
}
}
else if (flag_code == CODE_64BIT
+ && !is_any_vex_encoding (&i.tm)
&& ((i.types[1].bitfield.qword
&& i.reg_operands == 1
&& i.imm_operands == 1
&& i.tm.extension_opcode == None
&& fits_in_unsigned_long (i.op[0].imms->X_add_number))
|| (fits_in_imm31 (i.op[0].imms->X_add_number)
- && (((i.tm.base_opcode == 0x24
- || i.tm.base_opcode == 0xa8)
- && i.tm.extension_opcode == None)
+ && ((i.tm.base_opcode == 0x24
+ || i.tm.base_opcode == 0xa8)
|| (i.tm.base_opcode == 0x80
&& i.tm.extension_opcode == 0x4)
|| ((i.tm.base_opcode == 0xf6
|| (i.types[0].bitfield.qword
&& ((i.reg_operands == 2
&& i.op[0].regs == i.op[1].regs
- && ((i.tm.base_opcode == 0x30
- || i.tm.base_opcode == 0x28)
- && i.tm.extension_opcode == None))
+ && (i.tm.base_opcode == 0x30
+ || i.tm.base_opcode == 0x28))
|| (i.reg_operands == 1
&& i.operands == 1
- && i.tm.base_opcode == 0x30
- && i.tm.extension_opcode == None)))))
+ && i.tm.base_opcode == 0x30)))))
{
/* Optimize: -O:
andq $imm31, %r64 -> andl $imm31, %r32
}
else if (optimize > 1
&& !optimize_for_space
+ && !is_any_vex_encoding (&i.tm)
&& i.reg_operands == 2
&& i.op[0].regs == i.op[1].regs
&& ((i.tm.base_opcode & ~(Opcode_D | 1)) == 0x8
if (i.types[x].bitfield.class == Reg && i.types[x].bitfield.byte
&& (i.op[x].regs->reg_flags & RegRex64) == 0)
{
+ gas_assert (!(i.op[x].regs->reg_flags & RegRex));
/* In case it is "hi" register, give up. */
if (i.op[x].regs->reg_num > 3)
as_bad (_("can't encode register '%s%s' in an "
if (i.rex == 0 && i.rex_encoding)
{
/* Check if we can add a REX_OPCODE byte. Look for 8 bit operand
- that uses legacy register. If it is "hi" register, don't add
+ that uses legacy register. If it is "hi" register, don't add
the REX_OPCODE byte. */
int x;
for (x = 0; x < 2; x++)
&& (i.op[x].regs->reg_flags & RegRex64) == 0
&& i.op[x].regs->reg_num > 3)
{
+ gas_assert (!(i.op[x].regs->reg_flags & RegRex));
i.rex_encoding = FALSE;
break;
}
i.dir_encoding = dir_encoding_store;
break;
case 0x4:
- /* {vex2} */
- i.vec_encoding = vex_encoding_vex2;
+ /* {vex} */
+ i.vec_encoding = vex_encoding_vex;
break;
case 0x5:
/* {vex3} */
i386_opcode_modifier suffix_check;
i386_operand_type operand_types [MAX_OPERANDS];
int addr_prefix_disp;
- unsigned int j;
- unsigned int found_cpu_match, size_match;
- unsigned int check_register;
+ unsigned int j, size_match, check_register;
enum i386_error specific_error = 0;
#if MAX_OPERANDS != 5
/* Check processor support. */
i.error = unsupported;
- found_cpu_match = (cpu_flags_match (t)
- == CPU_FLAGS_PERFECT_MATCH);
- if (!found_cpu_match)
+ if (cpu_flags_match (t) != CPU_FLAGS_PERFECT_MATCH)
continue;
/* Check AT&T mnemonic. */
/* Found either forward/reverse 2, 3 or 4 operand match here:
slip through to break. */
}
- if (!found_cpu_match)
- continue;
/* Check if vector and VEX operands are valid. */
if (check_VecOperands (t) || VEX_check_operands (t))
Destination register type is more significant than source
register type. crc32 in SSE4.2 prefers source register
type. */
- if (i.tm.base_opcode == 0xf20f38f0
- && i.types[0].bitfield.class == Reg)
- {
- if (i.types[0].bitfield.byte)
- i.suffix = BYTE_MNEM_SUFFIX;
- else if (i.types[0].bitfield.word)
- i.suffix = WORD_MNEM_SUFFIX;
- else if (i.types[0].bitfield.dword)
- i.suffix = LONG_MNEM_SUFFIX;
- else if (i.types[0].bitfield.qword)
- i.suffix = QWORD_MNEM_SUFFIX;
- }
-
- if (!i.suffix)
- {
- int op;
-
- if (i.tm.base_opcode == 0xf20f38f0)
- {
- /* We have to know the operand size for crc32. */
- as_bad (_("ambiguous memory operand size for `%s`"),
- i.tm.name);
- return 0;
- }
+ unsigned int op = i.tm.base_opcode != 0xf20f38f0 ? i.operands : 1;
- for (op = i.operands; --op >= 0;)
- if (i.tm.operand_types[op].bitfield.instance == InstanceNone
- || i.tm.operand_types[op].bitfield.instance == Accum)
- {
- if (i.types[op].bitfield.class != Reg)
- continue;
- if (i.types[op].bitfield.byte)
- i.suffix = BYTE_MNEM_SUFFIX;
- else if (i.types[op].bitfield.word)
- i.suffix = WORD_MNEM_SUFFIX;
- else if (i.types[op].bitfield.dword)
- i.suffix = LONG_MNEM_SUFFIX;
- else if (i.types[op].bitfield.qword)
- i.suffix = QWORD_MNEM_SUFFIX;
- else
- continue;
- break;
- }
- }
+ while (op--)
+ if (i.tm.operand_types[op].bitfield.instance == InstanceNone
+ || i.tm.operand_types[op].bitfield.instance == Accum)
+ {
+ if (i.types[op].bitfield.class != Reg)
+ continue;
+ if (i.types[op].bitfield.byte)
+ i.suffix = BYTE_MNEM_SUFFIX;
+ else if (i.types[op].bitfield.word)
+ i.suffix = WORD_MNEM_SUFFIX;
+ else if (i.types[op].bitfield.dword)
+ i.suffix = LONG_MNEM_SUFFIX;
+ else if (i.types[op].bitfield.qword)
+ i.suffix = QWORD_MNEM_SUFFIX;
+ else
+ continue;
+ break;
+ }
}
else if (i.suffix == BYTE_MNEM_SUFFIX)
{
else if (i.tm.opcode_modifier.defaultsize
&& !i.suffix
/* exclude fldenv/frstor/fsave/fstenv */
- && i.tm.opcode_modifier.no_ssuf
- /* exclude sysret */
- && i.tm.base_opcode != 0x0f07)
+ && i.tm.opcode_modifier.no_ssuf)
{
i.suffix = stackop_size;
if (stackop_size == LONG_MNEM_SUFFIX)
i.tm.name);
}
}
- else if (intel_syntax
- && !i.suffix
+ else if (!i.suffix
&& (i.tm.opcode_modifier.jump == JUMP_ABSOLUTE
|| i.tm.opcode_modifier.jump == JUMP_BYTE
|| i.tm.opcode_modifier.jump == JUMP_INTERSEGMENT
}
}
- if (!i.suffix)
+ if (!i.suffix
+ && !i.tm.opcode_modifier.defaultsize
+ && !i.tm.opcode_modifier.ignoresize)
{
- if (!intel_syntax)
+ unsigned int suffixes;
+
+ suffixes = !i.tm.opcode_modifier.no_bsuf;
+ if (!i.tm.opcode_modifier.no_wsuf)
+ suffixes |= 1 << 1;
+ if (!i.tm.opcode_modifier.no_lsuf)
+ suffixes |= 1 << 2;
+ if (!i.tm.opcode_modifier.no_ldsuf)
+ suffixes |= 1 << 3;
+ if (!i.tm.opcode_modifier.no_ssuf)
+ suffixes |= 1 << 4;
+ if (flag_code == CODE_64BIT && !i.tm.opcode_modifier.no_qsuf)
+ suffixes |= 1 << 5;
+
+ /* Are multiple suffixes allowed? */
+ if (suffixes & (suffixes - 1))
{
- if (i.tm.opcode_modifier.w)
+ if (intel_syntax)
{
- as_bad (_("no instruction mnemonic suffix given and "
- "no register operands; can't size instruction"));
+ as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
return 0;
}
- }
- else
- {
- unsigned int suffixes;
-
- suffixes = !i.tm.opcode_modifier.no_bsuf;
- if (!i.tm.opcode_modifier.no_wsuf)
- suffixes |= 1 << 1;
- if (!i.tm.opcode_modifier.no_lsuf)
- suffixes |= 1 << 2;
- if (!i.tm.opcode_modifier.no_ldsuf)
- suffixes |= 1 << 3;
- if (!i.tm.opcode_modifier.no_ssuf)
- suffixes |= 1 << 4;
- if (flag_code == CODE_64BIT && !i.tm.opcode_modifier.no_qsuf)
- suffixes |= 1 << 5;
-
- /* There are more than suffix matches. */
- if (i.tm.opcode_modifier.w
- || ((suffixes & (suffixes - 1))
- && !i.tm.opcode_modifier.defaultsize
- && !i.tm.opcode_modifier.ignoresize))
+ if (operand_check == check_error)
{
- as_bad (_("ambiguous operand size for `%s'"), i.tm.name);
+ as_bad (_("no instruction mnemonic suffix given and "
+ "no register operands; can't size `%s'"), i.tm.name);
return 0;
}
+ if (operand_check == check_warning)
+ as_warn (_("no instruction mnemonic suffix given and "
+ "no register operands; using default for `%s'"),
+ i.tm.name);
+
+ if (i.tm.opcode_modifier.floatmf)
+ i.suffix = SHORT_MNEM_SUFFIX;
+ else if (flag_code == CODE_16BIT)
+ i.suffix = WORD_MNEM_SUFFIX;
+ else if (!i.tm.opcode_modifier.no_lsuf)
+ i.suffix = LONG_MNEM_SUFFIX;
+ else
+ i.suffix = QWORD_MNEM_SUFFIX;
}
}
#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
/* For x32, add a dummy REX_OPCODE prefix for mov/add with
R_X86_64_GOTTPOFF relocation so that linker can safely
- perform IE->LE optimization. */
+ perform IE->LE optimization. A dummy REX_OPCODE prefix
+ is also needed for lea with R_X86_64_GOTPC32_TLSDESC
+ relocation for GDesc -> IE/LE optimization. */
if (x86_elf_abi == X86_64_X32_ABI
&& i.operands == 2
- && i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
+ && (i.reloc[0] == BFD_RELOC_X86_64_GOTTPOFF
+ || i.reloc[0] == BFD_RELOC_X86_64_GOTPC32_TLSDESC)
&& i.prefix[REX_PREFIX] == 0)
add_prefix (REX_OPCODE);
#endif