This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Modify GNU assembler to follow SVME spec
- From: "H.J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Wed, 5 Sep 2007 06:34:55 -0700
- Subject: PATCH: Modify GNU assembler to follow SVME spec
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 -----