This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Optimize REP prefix check


Hi,

I checked in this patch to optimize REP prefix check.


H.J.
---
gas/

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.

gas/testsuite/

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.
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;
 }
 
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index f03dcf3..a8743e9 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 0000000..5579011
--- /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 0000000..65211ac
--- /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 0000000..8d582f2
--- /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 0000000..bccf948
--- /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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]