CPU_EPT_FLAGS, 0 },
{ STRING_COMMA_LEN (".lzcnt"), PROCESSOR_UNKNOWN,
CPU_LZCNT_FLAGS, 0 },
+ { STRING_COMMA_LEN (".popcnt"), PROCESSOR_UNKNOWN,
+ CPU_POPCNT_FLAGS, 0 },
{ STRING_COMMA_LEN (".hle"), PROCESSOR_UNKNOWN,
CPU_HLE_FLAGS, 0 },
{ STRING_COMMA_LEN (".rtm"), PROCESSOR_UNKNOWN,
if (!t->opcode_modifier.d)
{
-mismatch:
+ mismatch:
if (!match)
i.error = operand_size_mismatch;
return match;
if (given.bitfield.baseindex == overlap.bitfield.baseindex)
return 1;
-mismatch:
+ mismatch:
i.error = operand_type_mismatch;
return 0;
}
/* Now we've parsed the mnemonic into a set of templates, and have the
operands at hand. */
- /* All intel opcodes have reversed operands except for "bound" and
- "enter". We also don't reverse intersegment "jmp" and "call"
- instructions with 2 immediate operands so that the immediate segment
- precedes the offset, as it does when in AT&T mode. */
+ /* All Intel opcodes have reversed operands except for "bound", "enter"
+ "monitor*", and "mwait*". We also don't reverse intersegment "jmp"
+ and "call" instructions with 2 immediate operands so that the immediate
+ segment precedes the offset, as it does when in AT&T mode. */
if (intel_syntax
&& i.operands > 1
&& (strcmp (mnemonic, "bound") != 0)
&& (strcmp (mnemonic, "invlpga") != 0)
+ && (strncmp (mnemonic, "monitor", 7) != 0)
+ && (strncmp (mnemonic, "mwait", 5) != 0)
&& !(operand_type_check (i.types[0], imm)
&& operand_type_check (i.types[1], imm)))
swap_operands ();
if (!current_templates)
{
-check_suffix:
+ check_suffix:
if (mnem_p > mnemonic)
{
/* See if we can get a match by trimming off a suffix. */
if (!t->opcode_modifier.d)
continue;
-check_reverse:
+ check_reverse:
if (!(size_match & MATCH_REVERSE))
continue;
/* Try reversing direction of operands. */
else if (i.tm.opcode_modifier.size == SIZE64)
i.suffix = QWORD_MNEM_SUFFIX;
else if (i.reg_operands
- && (i.operands > 1 || i.types[0].bitfield.class == Reg))
+ && (i.operands > 1 || i.types[0].bitfield.class == Reg)
+ && !i.tm.opcode_modifier.addrprefixopreg)
{
unsigned int numop = i.operands;
/* Now select between word & dword operations via the operand
size prefix, except for instructions that will ignore this
prefix anyway. */
- if (i.reg_operands > 0
- && i.types[0].bitfield.class == Reg
- && i.tm.opcode_modifier.addrprefixopreg
- && (i.tm.operand_types[0].bitfield.instance == Accum
- || i.operands == 1))
- {
- /* The address size override prefix changes the size of the
- first operand. */
- if ((flag_code == CODE_32BIT
- && i.op[0].regs->reg_type.bitfield.word)
- || (flag_code != CODE_32BIT
- && i.op[0].regs->reg_type.bitfield.dword))
- if (!add_prefix (ADDR_PREFIX_OPCODE))
- return 0;
- }
- else if (i.suffix != QWORD_MNEM_SUFFIX
- && !i.tm.opcode_modifier.ignoresize
- && !i.tm.opcode_modifier.floatmf
- && !is_any_vex_encoding (&i.tm)
- && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
- || (flag_code == CODE_64BIT
- && i.tm.opcode_modifier.jump == JUMP_BYTE)))
+ if (i.suffix != QWORD_MNEM_SUFFIX
+ && !i.tm.opcode_modifier.ignoresize
+ && !i.tm.opcode_modifier.floatmf
+ && !is_any_vex_encoding (&i.tm)
+ && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
+ || (flag_code == CODE_64BIT
+ && i.tm.opcode_modifier.jump == JUMP_BYTE)))
{
unsigned int prefix = DATA_PREFIX_OPCODE;
break;
}
- if (i.reg_operands != 0
- && i.operands > 1
- && i.tm.opcode_modifier.addrprefixopreg
- && i.tm.operand_types[0].bitfield.instance != Accum)
+ if (i.tm.opcode_modifier.addrprefixopreg)
{
- /* Check invalid register operand when the address size override
- prefix changes the size of register operands. */
- unsigned int op;
- enum { need_word, need_dword, need_qword } need;
+ gas_assert (!i.suffix);
+ gas_assert (i.reg_operands);
+
+ if (i.tm.operand_types[0].bitfield.instance == Accum
+ || i.operands == 1)
+ {
+ /* The address size override prefix changes the size of the
+ first operand. */
+ if (flag_code == CODE_64BIT
+ && i.op[0].regs->reg_type.bitfield.word)
+ {
+ as_bad (_("16-bit addressing unavailable for `%s'"),
+ i.tm.name);
+ return 0;
+ }
- if (flag_code == CODE_32BIT)
- need = i.prefix[ADDR_PREFIX] ? need_word : need_dword;
+ if ((flag_code == CODE_32BIT
+ ? i.op[0].regs->reg_type.bitfield.word
+ : i.op[0].regs->reg_type.bitfield.dword)
+ && !add_prefix (ADDR_PREFIX_OPCODE))
+ return 0;
+ }
else
{
- if (i.prefix[ADDR_PREFIX])
+ /* Check invalid register operand when the address size override
+ prefix changes the size of register operands. */
+ unsigned int op;
+ enum { need_word, need_dword, need_qword } need;
+
+ if (flag_code == CODE_32BIT)
+ need = i.prefix[ADDR_PREFIX] ? need_word : need_dword;
+ else if (i.prefix[ADDR_PREFIX])
need = need_dword;
else
need = flag_code == CODE_64BIT ? need_qword : need_word;
- }
- for (op = 0; op < i.operands; op++)
- if (i.types[op].bitfield.class == Reg
- && ((need == need_word
- && !i.op[op].regs->reg_type.bitfield.word)
- || (need == need_dword
- && !i.op[op].regs->reg_type.bitfield.dword)
- || (need == need_qword
- && !i.op[op].regs->reg_type.bitfield.qword)))
- {
- as_bad (_("invalid register operand size for `%s'"),
- i.tm.name);
- return 0;
- }
+ for (op = 0; op < i.operands; op++)
+ {
+ if (i.types[op].bitfield.class != Reg)
+ continue;
+
+ switch (need)
+ {
+ case need_word:
+ if (i.op[op].regs->reg_type.bitfield.word)
+ continue;
+ break;
+ case need_dword:
+ if (i.op[op].regs->reg_type.bitfield.dword)
+ continue;
+ break;
+ case need_qword:
+ if (i.op[op].regs->reg_type.bitfield.qword)
+ continue;
+ break;
+ }
+
+ as_bad (_("invalid register operand size for `%s'"),
+ i.tm.name);
+ return 0;
+ }
+ }
}
return 1;
}
else
{
-duplicate:
+ duplicate:
i.operands++;
i.reg_operands++;
i.tm.operands++;
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_X87;
if (i.has_regmmx
|| i.tm.base_opcode == 0xf77 /* emms */
- || i.tm.base_opcode == 0xf0e /* femms */)
+ || i.tm.base_opcode == 0xf0e /* femms */
+ || i.tm.base_opcode == 0xf2a /* cvtpi2ps */
+ || i.tm.base_opcode == 0x660f2a /* cvtpi2pd */)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_MMX;
if (i.has_regxmm)
x86_feature_2_used |= GNU_PROPERTY_X86_FEATURE_2_XMM;
else
return 1;
-bad_address:
+ bad_address:
as_bad (_("`%s' is not a valid %s expression"),
operand_string, kind);
return 0;