Optimize REP prefix check
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 28 Feb 2013 20:50:19 +0000 (20:50 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 28 Feb 2013 20:50:19 +0000 (20:50 +0000)
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
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/inval-rep.l [new file with mode: 0644]
gas/testsuite/gas/i386/inval-rep.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-inval-rep.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-inval-rep.s [new file with mode: 0644]

index fe6741d47989def7e380f37f844ae596dd8be095..0b9e12ee5d90d0b65f2b06dcc56fd4813d4e9dfe 100644 (file)
@@ -1,3 +1,10 @@
+2013-02-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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  <yufeng.zhang@arm.com>
 
        * config/tc-aarch64.c (aarch64_features): Add the 'crc' option.
index 737cc2eb3eacbad1f2def66a37bdbd6f52284e95..71155e4c3c9a105fe8a192297e20d649ffc6d37c 100644 (file)
@@ -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;
 }
 
index cb3933625b46aa0bb117cf17a2b282b90a22253f..5107894513de735a24ef7c6a5274fc07160f4ca9 100644 (file)
@@ -1,3 +1,12 @@
+2013-02-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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  <yufeng.zhang@arm.com>
 
        * gas/aarch64/crc32.s: New test.
index f03dcf3346f34245e13174ba58f13a4b962cd65f..a8743e98ba75d7a9d18e542b8cbb01702e336f09 100644 (file)
@@ -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 (file)
index 0000000..5579011
--- /dev/null
@@ -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 (file)
index 0000000..65211ac
--- /dev/null
@@ -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 (file)
index 0000000..8d582f2
--- /dev/null
@@ -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 (file)
index 0000000..bccf948
--- /dev/null
@@ -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