X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-i386.c;h=62b7cfbe6c7556f1a2d66d546893309a94726adf;hb=dc1e8a474f904419abaa27da4be5b0f735a87255;hp=acade9de48a543c7334f2b78ab956bd65b1a45f1;hpb=b9915cbc7d3ac2b9cd136248defbf9538b9a9bcf;p=thirdparty%2Fbinutils-gdb.git diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index acade9de48a..62b7cfbe6c7 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1055,6 +1055,8 @@ static const arch_entry cpu_arch[] = 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, @@ -2187,7 +2189,7 @@ operand_size_match (const insn_template *t) if (!t->opcode_modifier.d) { -mismatch: + mismatch: if (!match) i.error = operand_size_mismatch; return match; @@ -2242,7 +2244,7 @@ operand_type_match (i386_operand_type overlap, if (given.bitfield.baseindex == overlap.bitfield.baseindex) return 1; -mismatch: + mismatch: i.error = operand_type_mismatch; return 0; } @@ -4324,14 +4326,16 @@ md_assemble (char *line) /* 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 (); @@ -4788,7 +4792,7 @@ parse_insn (char *line, char *mnemonic) if (!current_templates) { -check_suffix: + check_suffix: if (mnem_p > mnemonic) { /* See if we can get a match by trimming off a suffix. */ @@ -6026,7 +6030,7 @@ match_template (char mnem_suffix) if (!t->opcode_modifier.d) continue; -check_reverse: + check_reverse: if (!(size_match & MATCH_REVERSE)) continue; /* Try reversing direction of operands. */ @@ -6296,7 +6300,8 @@ process_suffix (void) 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; @@ -6611,28 +6616,13 @@ process_suffix (void) /* 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; @@ -6661,39 +6651,70 @@ process_suffix (void) 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; @@ -7054,7 +7075,7 @@ process_operands (void) } else { -duplicate: + duplicate: i.operands++; i.reg_operands++; i.tm.operands++; @@ -8615,7 +8636,9 @@ output_insn (void) 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; @@ -10381,7 +10404,7 @@ i386_index_check (const char *operand_string) else return 1; -bad_address: + bad_address: as_bad (_("`%s' is not a valid %s expression"), operand_string, kind); return 0;