PATCH: Fix cmpxchg8b in Intel mode

H.J. Lu hjl@lucon.org
Tue Aug 28 20:02:00 GMT 2007


I am checking this patch to fix cmpxchg8b in Intel mode. I also
updated disassembler for instructions with one memory operand. I
added testcases for those instructions.


H.J.
----
gas/

2007-08-28  H.J. Lu  <hongjiu.lu@intel.com>

	* config/tc-i386.c (process_suffix): Handle cmpxchg8b in
	Intel mode.

gas/testsuite/

2007-08-28  H.J. Lu  <hongjiu.lu@intel.com>

	* gas/i386/mem.s: New. Add tests for instructions with one
	memory operand.
	* gas/i386/x86-64-mem.s: Likewise.

	* gas/i386/mem-intel.d: Updated.
	* gas/i386/mem.d: Likewise.
	* gas/i386/x86-64-mem-intel.d: Likewise.
	* gas/i386/x86-64-mem.d: Likewise.

opcodes/

2007-08-28  H.J. Lu  <hongjiu.lu@intel.com>

	* i386-dis.c (Md): 
	(grps): Don't pass w_mode to invlpg.  Use M on fxsave and
	fxrstor.  Use Md on ldmxcsr and stmxcsr.

--- binutils/gas/config/tc-i386.c.mem	2007-08-24 09:01:55.000000000 -0700
+++ binutils/gas/config/tc-i386.c	2007-08-28 10:09:15.000000000 -0700
@@ -3032,11 +3032,17 @@ process_suffix (void)
 	  && (i.tm.opcode_modifier & NoRex64) == 0)
 	{
 	  /* Special case for xchg %rax,%rax.  It is NOP and doesn't
-	     need rex64.  */
-	  if (i.operands != 2
-	      || i.types [0] != (Acc | Reg64)
-	      || i.types [1] != (Acc | Reg64)
-	      || i.tm.base_opcode != 0x90)
+	     need rex64.  cmpxchg8b is also a special case. */
+	  if (! (i.operands == 2
+		 && i.tm.base_opcode == 0x90
+		 && i.tm.extension_opcode == None
+		 && i.types [0] == (Acc | Reg64)
+		 && i.types [1] == (Acc | Reg64))
+	      && ! (i.operands == 1
+		    && i.tm.base_opcode == 0xfc7
+		    && i.tm.extension_opcode == 1
+		    && (i.types [0] & Reg) == 0
+		    && (i.types [0] & AnyMem) != 0))
 	    i.rex |= REX_W;
 	}
 
--- binutils/gas/testsuite/gas/i386/i386.exp.mem	2007-08-28 08:43:08.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/i386.exp	2007-08-28 08:44:59.000000000 -0700
@@ -88,6 +88,8 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_list_test "inval-crc32" "-al"
     run_dump_test "simd"
     run_dump_test "simd-intel"
+    run_dump_test "mem"
+    run_dump_test "mem-intel"
 
     # These tests require support for 8 and 16 bit relocs,
     # so we only run them for ELF and COFF targets.
@@ -187,6 +189,8 @@ if [expr ([istarget "i*86-*-*"] || [ista
     run_list_test "x86-64-inval-crc32" "-al"
     run_dump_test "x86-64-simd"
     run_dump_test "x86-64-simd-intel"
+    run_dump_test "x86-64-mem"
+    run_dump_test "x86-64-mem-intel"
 
     if { ![istarget "*-*-aix*"]
       && ![istarget "*-*-beos*"]
--- binutils/gas/testsuite/gas/i386/mem-intel.d.mem	2007-08-28 08:44:59.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/mem-intel.d	2007-08-28 09:06:47.000000000 -0700
@@ -0,0 +1,41 @@
+#source: mem.s
+#as: -J
+#objdump: -dw -Mintel
+#name: i386 mem (Intel mode)
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \[esi\]
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr DWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr DWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush BYTE PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidtd  \[esi\]
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \[esi\]
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst QWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr DWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr DWORD PTR \[esi\]
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush BYTE PTR \[esi\]
+#pass
--- binutils/gas/testsuite/gas/i386/mem.d.mem	2007-08-28 08:44:59.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/mem.d	2007-08-28 09:07:51.000000000 -0700
@@ -0,0 +1,39 @@
+#objdump: -dw
+#name: i386 mem
+
+.*:     file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \(%esi\)
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b \(%esi\)
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld \(%esi\)
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear \(%esi\)
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  \(%esi\)
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidtl  \(%esi\)
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \(%esi\)
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b \(%esi\)
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld \(%esi\)
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear \(%esi\)
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  \(%esi\)
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr \(%esi\)
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush \(%esi\)
+#pass
--- binutils/gas/testsuite/gas/i386/mem.s.mem	2007-08-28 08:44:59.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/mem.s	2007-08-28 09:04:50.000000000 -0700
@@ -0,0 +1,39 @@
+# Check instructions with one memory operand
+
+	.text
+_start:
+
+sgdt (%esi)
+sidt (%esi)
+lgdt (%esi)
+lidt (%esi)
+invlpg (%esi)
+cmpxchg8b (%esi)
+vmptrld (%esi)
+vmclear (%esi)
+vmxon (%esi)
+vmptrst (%esi)
+fxsave (%esi)
+fxrstor (%esi)
+ldmxcsr (%esi)
+stmxcsr (%esi)
+clflush (%esi)
+
+.intel_syntax noprefix
+sgdt [esi]
+sidt [esi]
+lgdt [esi]
+lidt [esi]
+invlpg [esi]
+cmpxchg8b qword ptr [esi]
+vmptrld qword ptr [esi]
+vmclear qword ptr [esi]
+vmxon qword ptr [esi]
+vmptrst qword ptr [esi]
+fxsave [esi]
+fxrstor [esi]
+ldmxcsr dword ptr [esi]
+stmxcsr dword ptr [esi]
+clflush byte ptr [esi]
+
+.p2align 4,0
--- binutils/gas/testsuite/gas/i386/x86-64-mem-intel.d.mem	2007-08-28 08:44:59.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-mem-intel.d	2007-08-28 09:17:02.000000000 -0700
@@ -0,0 +1,43 @@
+#source: x86-64-mem.s
+#as: -J
+#objdump: -dw -Mintel
+#name: x86-64 mem (Intel mode)
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \[rsi\]
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	48 0f c7 0e          	cmpxchg16b OWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr DWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr DWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush BYTE PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidt   \[rsi\]
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \[rsi\]
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	48 0f c7 0e          	cmpxchg16b OWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst QWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr DWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr DWORD PTR \[rsi\]
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush BYTE PTR \[rsi\]
+#pass
--- binutils/gas/testsuite/gas/i386/x86-64-mem.d.mem	2007-08-28 08:44:59.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-mem.d	2007-08-28 09:17:16.000000000 -0700
@@ -0,0 +1,42 @@
+#as: -J
+#objdump: -dw
+#name: x86-64 mem
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \(%rsi\)
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b \(%rsi\)
+[ 	]*[a-f0-9]+:	48 0f c7 0e          	cmpxchg16b \(%rsi\)
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld \(%rsi\)
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear \(%rsi\)
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  \(%rsi\)
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 06             	sgdt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 0e             	sidt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 16             	lgdt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 1e             	lidt   \(%rsi\)
+[ 	]*[a-f0-9]+:	0f 01 3e             	invlpg \(%rsi\)
+[ 	]*[a-f0-9]+:	0f c7 0e             	cmpxchg8b \(%rsi\)
+[ 	]*[a-f0-9]+:	48 0f c7 0e          	cmpxchg16b \(%rsi\)
+[ 	]*[a-f0-9]+:	0f c7 36             	vmptrld \(%rsi\)
+[ 	]*[a-f0-9]+:	66 0f c7 36          	vmclear \(%rsi\)
+[ 	]*[a-f0-9]+:	f3 0f c7 36          	vmxon  \(%rsi\)
+[ 	]*[a-f0-9]+:	0f c7 3e             	vmptrst \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 06             	fxsave \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 0e             	fxrstor \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 16             	ldmxcsr \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 1e             	stmxcsr \(%rsi\)
+[ 	]*[a-f0-9]+:	0f ae 3e             	clflush \(%rsi\)
+#pass
--- binutils/gas/testsuite/gas/i386/x86-64-mem.s.mem	2007-08-28 08:44:59.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-mem.s	2007-08-28 09:14:47.000000000 -0700
@@ -0,0 +1,41 @@
+# Check 64bit instructions with one memory operand
+
+	.text
+_start:
+
+sgdt (%rsi)
+sidt (%rsi)
+lgdt (%rsi)
+lidt (%rsi)
+invlpg (%rsi)
+cmpxchg8b (%rsi)
+cmpxchg16b (%rsi)
+vmptrld (%rsi)
+vmclear (%rsi)
+vmxon (%rsi)
+vmptrst (%rsi)
+fxsave (%rsi)
+fxrstor (%rsi)
+ldmxcsr (%rsi)
+stmxcsr (%rsi)
+clflush (%rsi)
+
+.intel_syntax noprefix
+sgdt [rsi]
+sidt [rsi]
+lgdt [rsi]
+lidt [rsi]
+invlpg [rsi]
+cmpxchg8b qword ptr [rsi]
+cmpxchg16b oword ptr [rsi]
+vmptrld qword ptr [rsi]
+vmclear qword ptr [rsi]
+vmxon qword ptr [rsi]
+vmptrst qword ptr [rsi]
+fxsave [rsi]
+fxrstor [rsi]
+ldmxcsr dword ptr [rsi]
+stmxcsr dword ptr [rsi]
+clflush byte ptr [rsi]
+
+.p2align 4,0
--- binutils/opcodes/i386-dis.c.mem	2007-08-02 13:38:00.000000000 -0700
+++ binutils/opcodes/i386-dis.c	2007-08-28 10:13:54.000000000 -0700
@@ -215,6 +215,7 @@ fetch_data (struct disassemble_info *inf
 #define Ew { OP_E, w_mode }
 #define M { OP_M, 0 }		/* lea, lgdt, etc. */
 #define Ma { OP_M, v_mode }
+#define Md { OP_M, d_mode }
 #define Mp { OP_M, f_mode }		/* 32 or 48 bit memory operand for LDS, LES etc */
 #define Mq { OP_M, q_mode }
 #define Gb { OP_G, b_mode }
@@ -1702,7 +1703,7 @@ static const struct dis386 grps[][8] = {
     { "smswD",	{ Sv } },
     { "(bad)",	{ XX } },
     { "lmsw",	{ Ew } },
-    { "invlpg",	{ { INVLPG_Fixup, w_mode } } },
+    { "invlpg",	{ { INVLPG_Fixup, 0 } } },
   },
   /* GRP8 */
   {
@@ -1783,14 +1784,14 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP15 */
   {
-    { "fxsave",		{ Ev } },
-    { "fxrstor",	{ Ev } },
-    { "ldmxcsr",	{ Ev } },
-    { "stmxcsr",	{ Ev } },
+    { "fxsave",		{ M } },
+    { "fxrstor",	{ M } },
+    { "ldmxcsr",	{ Md } },
+    { "stmxcsr",	{ Md } },
     { "(bad)",		{ XX } },
     { "lfence",		{ { OP_0fae, 0 } } },
     { "mfence",		{ { OP_0fae, 0 } } },
-    { "clflush",	{ { OP_0fae, 0 } } },
+    { "clflush",	{ { OP_0fae, b_mode } } },
   },
   /* GRP16 */
   {
@@ -5908,7 +5909,11 @@ OP_0fae (int bytemode, int sizeflag)
   if (modrm.mod == 3)
     {
       if (modrm.reg == 7)
-	strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
+	{
+	  bytemode = 0;
+	  strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1,
+		  "sfence");
+	}
 
       if (modrm.reg < 5 || modrm.rm != 0)
 	{



More information about the Binutils mailing list