PATCH: Modify GNU assembler to follow SVME spec

Jan Beulich jbeulich@novell.com
Wed Sep 5 17:26:00 GMT 2007


Based on the original discussion, where I convinced AMD (I don't remember who
posted the patch back then) that accesses that are memory like should be
represented by memory like operand syntax, I object to this patch. Jan

>>> "H.J. Lu" <hjl@lucon.org> 09/05/07 3:34 PM >>>
This is the patch I checked in after confirmed by AMD.



H.J.
----- Forwarded message from "H.J. Lu" <hjl@lucon.org> -----

Date: Thu, 30 Aug 2007 22:24:01 -0700
From: "H.J. Lu" <hjl@lucon.org>
To: "rajagopal, dwarak" <dwarak.rajagopal@amd.com>
Cc: "Meissner, Michael" <michael.meissner@amd.com>,
	"Harle, Christophe" <christophe.harle@amd.com>
Subject: Re: Modify GNU assembler to follow SVME spec
User-Agent: Mutt/1.5.14 (2007-02-12)

On Thu, Aug 30, 2007 at 07:19:02PM -0500, rajagopal, dwarak wrote:
> H.J.,
> 
> Yes, SVM instructions have register only operand.  So please fix this.
> 

Could you please take a look at this patch? I will check it in on
Aug. 31 if there are no objections from you.

Thanks.


H.J.
----
gas/testsuite/

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

	* gas/i386/svme.s: Updated to accept eax in 32bit and rax in
	64bit.
	* gas/i386/svme.d: Updated.
	* gas/i386/svme64.d: Likewise.

opcodes/

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

	* i386-dis.c (SVME_Fixup): Removed.
	(OPC_EXT_39): New.
	(OPC_EXT_RM_6): Likewise.
	(grps): Use OPC_EXT_39.
	(opc_ext_table): Add OPC_EXT_39.
	(opc_ext_rm_table): Add OPC_EXT_RM_6.

	* i386-opc.tbl: Correct SVME instructions to take register
	operand only.
	* i386-tbl.h: Regenerated.

--- binutils/gas/testsuite/gas/i386/svme.d.bar	2005-07-05 00:16:52.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/svme.d	2007-08-30 22:09:41.000000000 -0700
@@ -15,15 +15,15 @@ Disassembly of section .text:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 d8[	 ]+vmrun[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 db[	 ]+vmsave[	 ]*
 [0-9a-f]+ <att32>:
-[	 ]*[0-9a-f]+:[	 ]+0f 01 de[	 ]+skinit[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 df[	 ]+invlpga[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 da[	 ]+vmload[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 d8[	 ]+vmrun[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 db[	 ]+vmsave[	 ]*
-[0-9a-f]+ <intel32>:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 de[	 ]+skinit[	 ]*
+[0-9a-f]+ <intel32>:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 df[	 ]+invlpga[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 da[	 ]+vmload[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 d8[	 ]+vmrun[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 db[	 ]+vmsave[	 ]*
+[	 ]*[0-9a-f]+:[	 ]+0f 01 de[	 ]+skinit[	 ]*
 #pass
--- binutils/gas/testsuite/gas/i386/svme.s.bar	2005-07-05 00:16:52.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/svme.s	2007-08-30 22:11:45.000000000 -0700
@@ -18,19 +18,21 @@ common:
 
 .ifdef __amd64__
 att64:
-	do_args	(%rax), %ecx
-.endif
+	do_args	%rax, %ecx
+.else
 att32:
-	skinit	(%eax)
-	do_args	(%eax), %ecx
+	do_args	%eax, %ecx
+.endif
+	skinit	%eax
 
 .intel_syntax noprefix
 .ifdef __amd64__
 intel64:
-	do_args	[rax], ecx
-.endif
+	do_args	rax, ecx
+.else
 intel32:
-	skinit	[eax]
-	do_args	[eax], ecx
+	do_args	eax, ecx
+.endif
+	skinit	eax
 
 	.p2align 4,0
--- binutils/gas/testsuite/gas/i386/svme64.d.bar	2005-07-05 00:16:52.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/svme64.d	2007-08-30 22:12:28.000000000 -0700
@@ -21,21 +21,11 @@ Disassembly of section .text:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 da[	 ]+vmload[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 d8[	 ]+vmrun[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 db[	 ]+vmsave[	 ]*
-[0-9a-f]+ <att32>:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 de[	 ]+skinit[	 ]*
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 df[	 ]+(addr32 )?invlpga[	 ]*\(%eax\),[	 ]*%ecx
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 da[	 ]+(addr32 )?vmload[	 ]*\(%eax\)
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 d8[	 ]+(addr32 )?vmrun[	 ]*\(%eax\)
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 db[	 ]+(addr32 )?vmsave[	 ]*\(%eax\)
 [0-9a-f]+ <intel64>:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 df[	 ]+invlpga[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 da[	 ]+vmload[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 d8[	 ]+vmrun[	 ]*
 [	 ]*[0-9a-f]+:[	 ]+0f 01 db[	 ]+vmsave[	 ]*
-[0-9a-f]+ <intel32>:
 [	 ]*[0-9a-f]+:[	 ]+0f 01 de[	 ]+skinit[	 ]*
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 df[	 ]+(addr32 )?invlpga[	 ]*\(%eax\),[	 ]*%ecx
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 da[	 ]+(addr32 )?vmload[	 ]*\(%eax\)
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 d8[	 ]+(addr32 )?vmrun[	 ]*\(%eax\)
-[	 ]*[0-9a-f]+:[	 ]+67 0f 01 db[	 ]+(addr32 )?vmsave[	 ]*\(%eax\)
 #pass
--- binutils/opcodes/i386-dis.c.bar	2007-08-30 08:17:58.000000000 -0700
+++ binutils/opcodes/i386-dis.c	2007-08-30 21:49:41.000000000 -0700
@@ -94,7 +94,6 @@ static void NOP_Fixup1 (int, int);
 static void NOP_Fixup2 (int, int);
 static void OP_3DNowSuffix (int, int);
 static void OP_SIMD_Suffix (int, int);
-static void SVME_Fixup (int, int);
 static void BadOp (void);
 static void REP_Fixup (int, int);
 static void CMPXCHG8B_Fixup (int, int);
@@ -596,6 +595,7 @@ fetch_data (struct disassemble_info *inf
 #define OPC_EXT_36 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 36 } }
 #define OPC_EXT_37 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 37 } }
 #define OPC_EXT_38 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 38 } }
+#define OPC_EXT_39 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 39 } }
 
 #define OPC_EXT_RM_0  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 0 } }
 #define OPC_EXT_RM_1  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 1 } }
@@ -603,6 +603,7 @@ fetch_data (struct disassemble_info *inf
 #define OPC_EXT_RM_3  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 3 } }
 #define OPC_EXT_RM_4  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 4 } }
 #define OPC_EXT_RM_5  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 5 } }
+#define OPC_EXT_RM_6  NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 6 } }
 
 typedef void (*op_rtn) (int bytemode, int sizeflag);
 
@@ -1541,7 +1542,7 @@ static const struct dis386 grps[][8] = {
     { OPC_EXT_6 },
     { OPC_EXT_7 },
     { OPC_EXT_8 },
-    { "lidt{Q|Q||}",	 { { SVME_Fixup, 0 } } },
+    { OPC_EXT_39 },
     { "smswD",	{ Sv } },
     { "(bad)",	{ XX } },
     { "lmsw",	{ Ew } },
@@ -3258,6 +3259,11 @@ static const struct dis386 opc_ext_table
     { "invlpg",		{ Mb } },
     { OPC_EXT_RM_5 },
   },
+  {
+    /* OPC_EXT_39 */
+    { "lidt{Q|Q||}",	{ M } },
+    { OPC_EXT_RM_6 },
+  },
 };
 
 static const struct dis386 opc_ext_rm_table[][8] = {
@@ -3327,6 +3333,17 @@ static const struct dis386 opc_ext_rm_ta
     { "(bad)",		{ XX } },
     { "(bad)",		{ XX } },
   },
+  {
+    /* OPC_EXT_RM_6 */
+    { "vmrun",		{ Skip_MODRM } },
+    { "vmmcall",	{ Skip_MODRM } },
+    { "vmload",		{ Skip_MODRM } },
+    { "vmsave",		{ Skip_MODRM } },
+    { "stgi",		{ Skip_MODRM } },
+    { "clgi",		{ Skip_MODRM } },
+    { "skinit",		{ Skip_MODRM } },
+    { "invlpga",	{ Skip_MODRM } },
+  },
 };
 
 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
@@ -6298,76 +6315,6 @@ OP_Monitor (int bytemode ATTRIBUTE_UNUSE
 }
 
 static void
-SVME_Fixup (int bytemode, int sizeflag)
-{
-  const char *alt;
-  char *p;
-
-  switch (*codep)
-    {
-    case 0xd8:
-      alt = "vmrun";
-      break;
-    case 0xd9:
-      alt = "vmmcall";
-      break;
-    case 0xda:
-      alt = "vmload";
-      break;
-    case 0xdb:
-      alt = "vmsave";
-      break;
-    case 0xdc:
-      alt = "stgi";
-      break;
-    case 0xdd:
-      alt = "clgi";
-      break;
-    case 0xde:
-      alt = "skinit";
-      break;
-    case 0xdf:
-      alt = "invlpga";
-      break;
-    default:
-      OP_M (bytemode, sizeflag);
-      return;
-    }
-  /* Override "lidt".  */
-  p = obuf + strlen (obuf) - 4;
-  /* We might have a suffix.  */
-  if (*p == 'i')
-    --p;
-  strcpy (p, alt);
-  if (!(prefixes & PREFIX_ADDR))
-    {
-      ++codep;
-      return;
-    }
-  used_prefixes |= PREFIX_ADDR;
-  switch (*codep++)
-    {
-    case 0xdf:
-      strcpy (op_out[1], names32[1]);
-      two_source_ops = 1;
-	  /* Fall through.  */
-    case 0xd8:
-    case 0xda:
-    case 0xdb:
-      *obufp++ = open_char;
-      if (address_mode == mode_64bit || (sizeflag & AFLAG))
-        alt = names32[0];
-      else
-        alt = names16[0];
-      strcpy (obufp, alt);
-      obufp += strlen (alt);
-      *obufp++ = close_char;
-      *obufp = '\0';
-      break;
-    }
-}
-
-static void
 BadOp (void)
 {
   /* Throw away prefixes and 1st. opcode byte.  */
--- binutils/opcodes/i386-opc.tbl.bar	2007-08-09 06:54:28.000000000 -0700
+++ binutils/opcodes/i386-opc.tbl	2007-08-30 22:15:23.000000000 -0700
@@ -1460,18 +1460,30 @@ rdtscp, 0, 0xf01, 0xf9, CpuSledgehammer,
 // AMD Pacifica additions.
 clgi, 0, 0xf01, 0xdd, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
 invlpga, 0, 0xf01, 0xdf, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
-// Need to ensure only "invlpga ...,%ecx" is accepted.
-invlpga, 2, 0xf01, 0xdf, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg32 }
+// FIXME: Need to ensure only "invlpga %eax,%ecx" is accepted.
+invlpga, 2, 0xf01, 0xdf, CpuSVME|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { Reg32, Reg32 }
+// FIXME: Need to ensure only "invlpga %rax,%ecx" is accepted.
+invlpga, 2, 0xf01, 0xdf, CpuSVME|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64, { Reg64, Reg32 }
 skinit, 0, 0xf01, 0xde, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
-skinit, 1, 0xf01, 0xde, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+// FIXME: Need to ensure only "skinit %eax" is accepted.
+skinit, 1, 0xf01, 0xde, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { Reg32 }
 stgi, 0, 0xf01, 0xdc, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
 vmload, 0, 0xf01, 0xda, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
-vmload, 1, 0xf01, 0xda, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+// FIXME: Need to ensure only "vmload %eax" is accepted.
+vmload, 1, 0xf01, 0xda, CpuSVME|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { Reg32 }
+// FIXME: Need to ensure only "vmload %rax" is accepted.
+vmload, 1, 0xf01, 0xda, CpuSVME|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64, { Reg64 }
 vmmcall, 0, 0xf01, 0xd9, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
 vmrun, 0, 0xf01, 0xd8, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
-vmrun, 1, 0xf01, 0xd8, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+// FIXME: Need to ensure only "vmrun %eax" is accepted.
+vmrun, 1, 0xf01, 0xd8, CpuSVME|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { Reg32 }
+// FIXME: Need to ensure only "vmrun %rax" is accepted.
+vmrun, 1, 0xf01, 0xd8, CpuSVME|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64, { Reg64 }
 vmsave, 0, 0xf01, 0xdb, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { 0 }
-vmsave, 1, 0xf01, 0xdb, CpuSVME, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+// FIXME: Need to ensure only "vmsave %eax" is accepted.
+vmsave, 1, 0xf01, 0xdb, CpuSVME|CpuNo64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt, { Reg32 }
+// FIXME: Need to ensure only "vmsave %rax" is accepted.
+vmsave, 1, 0xf01, 0xdb, CpuSVME|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64, { Reg64 }
 
 
 // SSE4a instructions
--- binutils/opcodes/i386-tbl.h.bar	2007-08-09 06:54:28.000000000 -0700
+++ binutils/opcodes/i386-tbl.h	2007-08-30 22:15:52.000000000 -0700
@@ -4189,40 +4189,53 @@ const template i386_optab[] =
   { "invlpga", 0, 0xf01, 0xdf, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
-  { "invlpga", 2, 0xf01, 0xdf, CpuSVME,
+  { "invlpga", 2, 0xf01, 0xdf, CpuSVME|CpuNo64,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
-    { BaseIndex|Disp8|Disp16|Disp32|Disp32S,
+    { Reg32,
+      Reg32 } },
+  { "invlpga", 2, 0xf01, 0xdf, CpuSVME|Cpu64,
+    No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64,
+    { Reg64,
       Reg32 } },
   { "skinit", 0, 0xf01, 0xde, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
   { "skinit", 1, 0xf01, 0xde, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
-    { BaseIndex|Disp8|Disp16|Disp32|Disp32S } },
+    { Reg32 } },
   { "stgi", 0, 0xf01, 0xdc, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
   { "vmload", 0, 0xf01, 0xda, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
-  { "vmload", 1, 0xf01, 0xda, CpuSVME,
+  { "vmload", 1, 0xf01, 0xda, CpuSVME|CpuNo64,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
-    { BaseIndex|Disp8|Disp16|Disp32|Disp32S } },
+    { Reg32 } },
+  { "vmload", 1, 0xf01, 0xda, CpuSVME|Cpu64,
+    No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64,
+    { Reg64 } },
   { "vmmcall", 0, 0xf01, 0xd9, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
   { "vmrun", 0, 0xf01, 0xd8, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
-  { "vmrun", 1, 0xf01, 0xd8, CpuSVME,
+  { "vmrun", 1, 0xf01, 0xd8, CpuSVME|CpuNo64,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
-    { BaseIndex|Disp8|Disp16|Disp32|Disp32S } },
+    { Reg32 } },
+  { "vmrun", 1, 0xf01, 0xd8, CpuSVME|Cpu64,
+    No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64,
+    { Reg64 } },
   { "vmsave", 0, 0xf01, 0xdb, CpuSVME,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
     { 0 } },
-  { "vmsave", 1, 0xf01, 0xdb, CpuSVME,
+  { "vmsave", 1, 0xf01, 0xdb, CpuSVME|CpuNo64,
     No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
-    { BaseIndex|Disp8|Disp16|Disp32|Disp32S } },
+    { Reg32 } },
+  { "vmsave", 1, 0xf01, 0xdb, CpuSVME|Cpu64,
+    No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt|NoRex64,
+    { Reg64 } },
   { "movntsd", 2, 0xf20f2b, None, CpuSSE4a,
     Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf,
     { RegXMM,




----- End forwarded message -----



More information about the Binutils mailing list