This is the mail archive of the binutils@sources.redhat.com 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: Add Intel VMX instructions


This patch adds Intel VMX instructions. I will check it in tomorrow.


H.J.
-----
gas/

2007-07-14  H.J. Lu <hongjiu.lu@intel.com>

	* gas/config/tc-i386.h (CpuVMX): New.
	(CpuUnknownFlags): Add CpuVMX.

gas/testsuite/

2007-07-14  H.J. Lu <hongjiu.lu@intel.com>

	* gas/i386/i386.exp: Add vmx and x86-64-vmx.

	* gas/i386/vmx.d: New file.
	* gas/i386/vmx.s: Likewise.
	* gas/i386/x86-64-vmx.d: Likewise.
	* gas/i386/x86-64-vmx.s: Likewise.

include/opcode/

2007-07-14  H.J. Lu <hongjiu.lu@intel.com>

	* i386.h (i386_optab): Support Intel VMX Instructions.

opcodes/

2007-07-14  H.J. Lu <hongjiu.lu@intel.com>

	* i386-dis.c (OP_VMX): New. Handle Intel VMX Instructions.
	(VMX_Fixup): New. Fix up Intel VMX Instructions.
	(Em): New.
	(Gm): New.
	(VM): New.
	(dis386_twobyte): Updated entries 0x78 and 0x79.
	(twobyte_has_modrm): Likewise.
	(grps): Use OP_VMX in the "sgdtIQ" entry. Updated GRP9.
	(OP_G): Handle m_mode.

--- binutils/gas/config/tc-i386.h.vmx	2005-07-06 12:16:04.338368844 -0700
+++ binutils/gas/config/tc-i386.h	2005-07-06 12:19:30.108436457 -0700
@@ -186,6 +186,7 @@ typedef struct
 #define CpuPNI	      CpuSSE3	/* Prescott New Instructions required */
 #define CpuPadLock    0x40000	/* VIA PadLock required */
 #define CpuSVME	      0x80000	/* AMD Secure Virtual Machine Ext-s required */
+#define CpuVMX	     0x100000	/* VMX Instructions required */
 
   /* These flags are set by gas depending on the flag_code.  */
 #define Cpu64	     0x4000000   /* 64bit support required  */
@@ -193,7 +194,7 @@ typedef struct
 
   /* The default value for unknown CPUs - enable all features to avoid problems.  */
 #define CpuUnknownFlags (Cpu086|Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \
-	|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuPNI \
+	|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuPNI|CpuVMX \
 	|Cpu3dnow|Cpu3dnowA|CpuK6|CpuAthlon|CpuPadLock|CpuSVME)
 
   /* the bits in opcode_modifier are used to generate the final opcode from
--- binutils/gas/testsuite/gas/i386/i386.exp.vmx	2005-07-06 08:45:43.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/i386.exp	2005-07-06 12:18:07.575046575 -0700
@@ -60,6 +60,7 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_dump_test "sub"
     run_dump_test "prescott"
     run_dump_test "sib"
+    run_dump_test "vmx"
 
     if {![istarget "*-*-aix*"]
 	&& (![is_elf_format] || [istarget "*-*-linux*"]
@@ -130,6 +131,7 @@ if [expr ([istarget "i*86-*-*"] || [ista
     run_list_test "x86-64-inval-seg" "-al"
     run_dump_test "x86-64-branch"
     run_dump_test "svme64"
+    run_dump_test "x86-64-vmx"
 
     # For ELF targets verify that @unwind works.
     if { ([istarget "*-*-elf*"] || [istarget "*-*-linux*"]
--- binutils/gas/testsuite/gas/i386/vmx.d.vmx	2005-07-06 12:17:03.615593769 -0700
+++ binutils/gas/testsuite/gas/i386/vmx.d	2005-07-06 12:17:03.615593769 -0700
@@ -0,0 +1,25 @@
+#objdump: -dw
+#name: i386 VMX
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <foo>:
+   0:	0f 01 c1 [ 	]*vmcall 
+   3:	0f 01 c2 [ 	]*vmlaunch 
+   6:	0f 01 c3 [ 	]*vmresume 
+   9:	0f 01 c4 [ 	]*vmxoff 
+   c:	66 0f c7 30 [ 	]*vmclear \(%eax\)
+  10:	0f c7 30 [ 	]*vmptrld \(%eax\)
+  13:	0f c7 38 [ 	]*vmptrst \(%eax\)
+  16:	f3 0f c7 30 [ 	]*vmxon  \(%eax\)
+  1a:	0f 78 c3 [ 	]*vmread %eax,%ebx
+  1d:	0f 78 c3 [ 	]*vmread %eax,%ebx
+  20:	0f 78 03 [ 	]*vmread %eax,\(%ebx\)
+  23:	0f 78 03 [ 	]*vmread %eax,\(%ebx\)
+  26:	0f 79 d8 [ 	]*vmwrite %eax,%ebx
+  29:	0f 79 d8 [ 	]*vmwrite %eax,%ebx
+  2c:	0f 79 18 [ 	]*vmwrite \(%eax\),%ebx
+  2f:	0f 79 18 [ 	]*vmwrite \(%eax\),%ebx
+	...
--- binutils/gas/testsuite/gas/i386/vmx.s.vmx	2005-07-06 12:17:03.615593769 -0700
+++ binutils/gas/testsuite/gas/i386/vmx.s	2005-07-06 12:17:03.615593769 -0700
@@ -0,0 +1,21 @@
+# VMX Instructions
+
+	.text
+foo:
+	vmcall
+	vmlaunch
+	vmresume
+	vmxoff
+	vmclear (%eax)
+	vmptrld (%eax)
+	vmptrst (%eax)
+	vmxon (%eax)
+	vmread %eax,%ebx
+	vmreadl %eax,%ebx
+	vmread %eax,(%ebx)
+	vmreadl %eax,(%ebx)
+	vmwrite %eax,%ebx
+	vmwritel %eax,%ebx
+	vmwrite (%eax),%ebx
+	vmwritel (%eax),%ebx
+	.p2align	4,0
--- binutils/gas/testsuite/gas/i386/x86-64-vmx.d.vmx	2005-07-06 12:17:03.616593604 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-vmx.d	2005-07-06 12:17:03.616593604 -0700
@@ -0,0 +1,25 @@
+#objdump: -dw
+#name: 64bit VMX
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <foo>:
+   0:	0f 01 c1 [ 	]*vmcall 
+   3:	0f 01 c2 [ 	]*vmlaunch 
+   6:	0f 01 c3 [ 	]*vmresume 
+   9:	0f 01 c4 [ 	]*vmxoff 
+   c:	66 0f c7 30 [ 	]*vmclear \(%rax\)
+  10:	0f c7 30 [ 	]*vmptrld \(%rax\)
+  13:	0f c7 38 [ 	]*vmptrst \(%rax\)
+  16:	f3 0f c7 30 [ 	]*vmxon  \(%rax\)
+  1a:	0f 78 c3 [ 	]*vmread %rax,%rbx
+  1d:	0f 78 c3 [ 	]*vmread %rax,%rbx
+  20:	0f 78 03 [ 	]*vmread %rax,\(%rbx\)
+  23:	0f 78 03 [ 	]*vmread %rax,\(%rbx\)
+  26:	0f 79 d8 [ 	]*vmwrite %rax,%rbx
+  29:	0f 79 d8 [ 	]*vmwrite %rax,%rbx
+  2c:	0f 79 18 [ 	]*vmwrite \(%rax\),%rbx
+  2f:	0f 79 18 [ 	]*vmwrite \(%rax\),%rbx
+	...
--- binutils/gas/testsuite/gas/i386/x86-64-vmx.s.vmx	2005-07-06 12:17:03.616593604 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-vmx.s	2005-07-06 12:17:03.616593604 -0700
@@ -0,0 +1,21 @@
+# VMX Instructions
+
+	.text
+foo:
+	vmcall
+	vmlaunch
+	vmresume
+	vmxoff
+	vmclear (%rax)
+	vmptrld (%rax)
+	vmptrst (%rax)
+	vmxon (%rax)
+	vmread %rax,%rbx
+	vmreadq %rax,%rbx
+	vmread %rax,(%rbx)
+	vmreadq %rax,(%rbx)
+	vmwrite %rax,%rbx
+	vmwriteq %rax,%rbx
+	vmwrite (%rax),%rbx
+	vmwriteq (%rax),%rbx
+	.p2align	4,0
--- binutils/include/opcode/i386.h.vmx	2005-07-06 08:45:41.000000000 -0700
+++ binutils/include/opcode/i386.h	2005-07-06 12:17:03.627591791 -0700
@@ -1347,6 +1347,20 @@ static const template i386_optab[] =
 /* Need to ensure only "mwait %eax,%ecx" is accepted.  */
 {"mwait",     2, 0x0f01, 0xc9, CpuPNI, NoSuf|ImmExt,	{ Reg32, Reg32, 0} },
 
+/* VMX instructions.  */
+{"vmcall",    0, 0x0f01, 0xc1, CpuVMX, NoSuf|ImmExt,	{ 0, 0, 0} },
+{"vmclear",   1, 0x660fc7,  6, CpuVMX, NoSuf|IgnoreSize|Modrm|NoRex64,	{ LLongMem, 0, 0} },
+{"vmlaunch",  0, 0x0f01, 0xc2, CpuVMX, NoSuf|ImmExt,	{ 0, 0, 0} },
+{"vmresume",  0, 0x0f01, 0xc3, CpuVMX, NoSuf|ImmExt,	{ 0, 0, 0} },
+{"vmptrld",   1, 0x0fc7,    6, CpuVMX, NoSuf|IgnoreSize|Modrm|NoRex64,	{ LLongMem, 0, 0} },
+{"vmptrst",   1, 0x0fc7,    7, CpuVMX, NoSuf|IgnoreSize|Modrm|NoRex64,	{ LLongMem, 0, 0} },
+{"vmread",    2, 0x0f78,    X, CpuVMX|CpuNo64, l_Suf|Modrm,{ Reg32, Reg32|LongMem, 0} },
+{"vmread",    2, 0x0f78,    X, CpuVMX|Cpu64, q_Suf|Modrm|NoRex64,{ Reg64, Reg64|LLongMem, 0} },
+{"vmwrite",   2, 0x0f79,    X, CpuVMX|CpuNo64, l_Suf|Modrm,{ Reg32|LongMem, Reg32, 0} },
+{"vmwrite",   2, 0x0f79,    X, CpuVMX|Cpu64, q_Suf|Modrm|NoRex64,{ Reg64|LLongMem, Reg64, 0} },
+{"vmxoff",    0, 0x0f01, 0xc4, CpuVMX, NoSuf|ImmExt,	{ 0, 0, 0} },
+{"vmxon",     1, 0xf30fc7,  6, CpuVMX, NoSuf|IgnoreSize|Modrm|NoRex64,	{ LLongMem, 0, 0} },
+
 /* AMD 3DNow! instructions.  */
 
 {"prefetch", 1, 0x0f0d,	   0, Cpu3dnow, NoSuf|IgnoreSize|Modrm,	{ ByteMem, 0, 0 } },
--- binutils/opcodes/i386-dis.c.vmx	2005-07-06 08:45:34.000000000 -0700
+++ binutils/opcodes/i386-dis.c	2005-07-06 12:17:03.632590966 -0700
@@ -88,6 +88,7 @@ static void OP_EX (int, int);
 static void OP_MS (int, int);
 static void OP_XS (int, int);
 static void OP_M (int, int);
+static void OP_VMX (int, int);
 static void OP_0fae (int, int);
 static void OP_0f07 (int, int);
 static void NOP_Fixup (int, int);
@@ -99,6 +100,7 @@ static void SVME_Fixup (int, int);
 static void INVLPG_Fixup (int, int);
 static void BadOp (void);
 static void SEG_Fixup (int, int);
+static void VMX_Fixup (int, int);
 
 struct dis_private {
   /* Points to first byte not fetched.  */
@@ -200,6 +202,7 @@ fetch_data (struct disassemble_info *inf
 #define Edqw OP_E, dqw_mode
 #define indirEv OP_indirE, branch_v_mode
 #define indirEp OP_indirE, f_mode
+#define Em OP_E, m_mode
 #define Ew OP_E, w_mode
 #define Ma OP_E, v_mode
 #define M OP_M, 0		/* lea, lgdt, etc. */
@@ -208,6 +211,7 @@ fetch_data (struct disassemble_info *inf
 #define Gv OP_G, v_mode
 #define Gd OP_G, d_mode
 #define Gdq OP_G, dq_mode
+#define Gm OP_G, m_mode
 #define Gw OP_G, w_mode
 #define Rd OP_Rd, d_mode
 #define Rm OP_Rd, m_mode
@@ -299,6 +303,7 @@ fetch_data (struct disassemble_info *inf
 #define EX OP_EX, v_mode
 #define MS OP_MS, v_mode
 #define XS OP_XS, v_mode
+#define VM OP_VMX, q_mode
 #define OPSUF OP_3DNowSuffix, 0
 #define OPSIMD OP_SIMD_Suffix, 0
 
@@ -915,8 +920,8 @@ static const struct dis386 dis386_twobyt
   { "pcmpeqd",		MX, EM, XX },
   { "emms",		XX, XX, XX },
   /* 78 */
-  { "(bad)",		XX, XX, XX },
-  { "(bad)",		XX, XX, XX },
+  { "vmread",		Em, Gm, XX },
+  { "vmwrite",		Gm, Em, XX },
   { "(bad)",		XX, XX, XX },
   { "(bad)",		XX, XX, XX },
   { PREGRP28 },
@@ -1102,7 +1107,7 @@ static const unsigned char twobyte_has_m
   /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
   /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
   /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
-  /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */
+  /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
   /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
   /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
   /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
@@ -1372,7 +1377,7 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP7 */
   {
-    { "sgdtIQ",	 M, XX, XX },
+    { "sgdtIQ", VMX_Fixup, 0, XX, XX },
     { "sidtIQ", PNI_Fixup, 0, XX, XX },
     { "lgdt{Q|Q||}",	 M, XX, XX },
     { "lidt{Q|Q||}",	 SVME_Fixup, 0, XX, XX },
@@ -1400,8 +1405,8 @@ static const struct dis386 grps[][8] = {
     { "(bad)",	XX, XX, XX },
     { "(bad)",	XX, XX, XX },
     { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
-    { "(bad)",	XX, XX, XX },
+    { "",	VM, XX, XX },		/* See OP_VMX.  */
+    { "vmptrst", Eq, XX, XX },
   },
   /* GRP10 */
   {
@@ -3487,6 +3492,12 @@ OP_G (int bytemode, int sizeflag)
 	oappend (names16[reg + add]);
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
+    case m_mode:
+      if (mode_64bit)
+	oappend (names64[reg + add]);
+      else
+	oappend (names32[reg + add]);
+      break;
     default:
       oappend (INTERNAL_DISASSEMBLER_ERROR);
       break;
@@ -4597,3 +4608,50 @@ SEG_Fixup (int extrachar, int sizeflag)
 
   OP_E (extrachar, sizeflag);
 }
+
+static void
+VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+  if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
+    {
+      /* Override "sgdt".  */
+      char *p = obuf + strlen (obuf) - 4;
+
+      /* We might have a suffix.  */
+      if (*p == 'i')
+	--p;
+
+      switch (rm)
+	{
+	case 1:
+	  strcpy (p, "vmcall");
+	  break;
+	case 2:
+	  strcpy (p, "vmlaunch");
+	  break;
+	case 3:
+	  strcpy (p, "vmresume");
+	  break;
+	case 4:
+	  strcpy (p, "vmxoff");
+	  break;
+	}
+
+      codep++;
+    }
+  else
+    OP_E (0, sizeflag);
+}
+
+static void
+OP_VMX (int bytemode, int sizeflag)
+{
+  used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
+  if (prefixes & PREFIX_DATA)
+    strcpy (obuf, "vmclear");
+  else if (prefixes & PREFIX_REPZ)
+    strcpy (obuf, "vmxon");
+  else
+    strcpy (obuf, "vmptrld");
+  OP_E (bytemode, sizeflag);
+}


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