aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2013-02-28 20:50:19 +0000
committerH.J. Lu <hjl.tools@gmail.com>2013-02-28 20:50:19 +0000
commitd5de92cf93a7ab93344b88c6bb54d1ebeadaa900 (patch)
treee1b47a8f29e24afc988c76b2cbcda6449cd17fc2 /gas/config
parentddb08e9caa02b478b6f4f3969cf5a7142fc0035e (diff)
downloadgdb-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.c37
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;
}