From d5de92cf93a7ab93344b88c6bb54d1ebeadaa900 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 28 Feb 2013 20:50:19 +0000 Subject: [PATCH] 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. --- gas/ChangeLog | 7 +++++ gas/config/tc-i386.c | 37 ++++++++--------------- gas/testsuite/ChangeLog | 9 ++++++ gas/testsuite/gas/i386/i386.exp | 2 ++ gas/testsuite/gas/i386/inval-rep.l | 15 +++++++++ gas/testsuite/gas/i386/inval-rep.s | 6 ++++ gas/testsuite/gas/i386/x86-64-inval-rep.l | 15 +++++++++ gas/testsuite/gas/i386/x86-64-inval-rep.s | 6 ++++ 8 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 gas/testsuite/gas/i386/inval-rep.l create mode 100644 gas/testsuite/gas/i386/inval-rep.s create mode 100644 gas/testsuite/gas/i386/x86-64-inval-rep.l create mode 100644 gas/testsuite/gas/i386/x86-64-inval-rep.s diff --git a/gas/ChangeLog b/gas/ChangeLog index fe6741d479..0b9e12ee5d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2013-02-28 H.J. Lu + + * 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. + 2013-02-28 Yufeng Zhang * config/tc-aarch64.c (aarch64_features): Add the 'crc' option. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 737cc2eb3e..71155e4c3c 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; } diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index cb3933625b..5107894513 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2013-02-28 H.J. Lu + + * 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. + 2013-02-28 Yufeng Zhang * gas/aarch64/crc32.s: New test. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index f03dcf3346..a8743e98ba 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -85,6 +85,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "ssse3" run_dump_test "rep" run_dump_test "rep-suffix" + run_list_test "inval-rep" "-al" run_dump_test "lock-1" run_dump_test "lock-1-intel" run_list_test "lockbad-1" "-al" @@ -366,6 +367,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-ssse3" run_dump_test "x86-64-rep" run_dump_test "x86-64-rep-suffix" + run_list_test "x86-64-inval-rep" "-al" run_dump_test "x86-64-lock-1" run_dump_test "x86-64-lock-1-intel" run_list_test "x86-64-lockbad-1" "-al" diff --git a/gas/testsuite/gas/i386/inval-rep.l b/gas/testsuite/gas/i386/inval-rep.l new file mode 100644 index 0000000000..5579011672 --- /dev/null +++ b/gas/testsuite/gas/i386/inval-rep.l @@ -0,0 +1,15 @@ +.*: Assembler messages: +.*:2: Error: .* +.*:3: Error: .* +.*:4: Error: .* +.*:5: Error: .* +.*:6: Error: .* +GAS LISTING .* + + +[ ]*1[ ]+\.text +[ ]*2[ ]+rep add %ebx, %eax +[ ]*3[ ]+repe add %ebx, %eax +[ ]*4[ ]+repz add %ebx, %eax +[ ]*5[ ]+repne add %ebx, %eax +[ ]*6[ ]+repnz add %ebx, %eax diff --git a/gas/testsuite/gas/i386/inval-rep.s b/gas/testsuite/gas/i386/inval-rep.s new file mode 100644 index 0000000000..65211aca4f --- /dev/null +++ b/gas/testsuite/gas/i386/inval-rep.s @@ -0,0 +1,6 @@ + .text + rep add %ebx, %eax + repe add %ebx, %eax + repz add %ebx, %eax + repne add %ebx, %eax + repnz add %ebx, %eax diff --git a/gas/testsuite/gas/i386/x86-64-inval-rep.l b/gas/testsuite/gas/i386/x86-64-inval-rep.l new file mode 100644 index 0000000000..8d582f20a9 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-inval-rep.l @@ -0,0 +1,15 @@ +.*: Assembler messages: +.*:2: Error: .* +.*:3: Error: .* +.*:4: Error: .* +.*:5: Error: .* +.*:6: Error: .* +GAS LISTING .* + + +[ ]*1[ ]+\.text +[ ]*2[ ]+rep add %rbx, %rax +[ ]*3[ ]+repe add %rbx, %rax +[ ]*4[ ]+repz add %rbx, %rax +[ ]*5[ ]+repne add %rbx, %rax +[ ]*6[ ]+repnz add %rbx, %rax diff --git a/gas/testsuite/gas/i386/x86-64-inval-rep.s b/gas/testsuite/gas/i386/x86-64-inval-rep.s new file mode 100644 index 0000000000..bccf9483ff --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-inval-rep.s @@ -0,0 +1,6 @@ + .text + rep add %rbx, %rax + repe add %rbx, %rax + repz add %rbx, %rax + repne add %rbx, %rax + repnz add %rbx, %rax