diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2013-02-28 20:50:19 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2013-02-28 20:50:19 +0000 |
commit | d5de92cf93a7ab93344b88c6bb54d1ebeadaa900 (patch) | |
tree | e1b47a8f29e24afc988c76b2cbcda6449cd17fc2 /gas/config | |
parent | ddb08e9caa02b478b6f4f3969cf5a7142fc0035e (diff) | |
download | gdb-d5de92cf93a7ab93344b88c6bb54d1ebeadaa900.zip gdb-d5de92cf93a7ab93344b88c6bb54d1ebeadaa900.tar.gz gdb-d5de92cf93a7ab93344b88c6bb54d1ebeadaa900.tar.bz2 |
Optimize REP prefix check
gas/
* config/tc-i386.c (_i386_insn): Add rep_prefix.
(md_assemble): Check if REP prefix is OK.
(parse_insn): Remove expecting_string_instruction. Set
i.rep_prefix.
gas/testsuite/
* gas/i386/i386.exp: Run inval-rep and x86-64-inval-rep.
* gas/i386/inval-rep.l: New file.
* gas/i386/inval-rep.s: Likewise.
* gas/i386/x86-64-inval-rep.l: Likewise.
* gas/i386/x86-64-inval-rep.s: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-i386.c | 37 |
1 files changed, 12 insertions, 25 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 737cc2e..71155e4 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -290,6 +290,9 @@ struct _i386_insn disp_encoding_32bit } disp_encoding; + /* REP prefix. */ + const char *rep_prefix; + /* Have HLE prefix. */ unsigned int have_hle; @@ -3211,6 +3214,14 @@ md_assemble (char *line) if (!add_prefix (FWAIT_OPCODE)) return; + /* Check if REP prefix is OK. */ + if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok) + { + as_bad (_("invalid instruction `%s' after `%s'"), + i.tm.name, i.rep_prefix); + return; + } + /* Check for lock without a lockable instruction. Destination operand must be memory unless it is xchg (0x86). */ if (i.prefix[LOCK_PREFIX] @@ -3359,9 +3370,6 @@ parse_insn (char *line, char *mnemonic) const insn_template *t; char *dot_p = NULL; - /* Non-zero if we found a prefix only acceptable with string insns. */ - const char *expecting_string_instruction = NULL; - while (1) { mnem_p = mnemonic; @@ -3433,7 +3441,7 @@ parse_insn (char *line, char *mnemonic) if (current_templates->start->cpu_flags.bitfield.cpuhle) i.have_hle = 1; else - expecting_string_instruction = current_templates->start->name; + i.rep_prefix = current_templates->start->name; break; default: break; @@ -3582,27 +3590,6 @@ skip: as_warn (_("use .code16 to ensure correct addressing mode")); } - /* Check for rep/repne without a string (or other allowed) instruction. */ - if (expecting_string_instruction) - { - static templates override; - - for (t = current_templates->start; t < current_templates->end; ++t) - if (t->opcode_modifier.repprefixok) - break; - if (t >= current_templates->end) - { - as_bad (_("expecting string instruction after `%s'"), - expecting_string_instruction); - return NULL; - } - for (override.start = t; t < current_templates->end; ++t) - if (!t->opcode_modifier.repprefixok) - break; - override.end = t; - current_templates = &override; - } - return l; } |