From 90700ea20faa973207ec0c5351ba73fbd7d38908 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 15 Jul 2005 13:49:53 +0000 Subject: [PATCH] gas/ 2007-07-15 H.J. Lu * gas/config/tc-i386.h (CpuVMX): New. (CpuUnknownFlags): Add CpuVMX. gas/testsuite/ 2007-07-15 H.J. Lu * 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-15 H.J. Lu * i386.h (i386_optab): Support Intel VMX Instructions. opcodes/ 2007-07-15 H.J. Lu * 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. --- gas/ChangeLog | 5 +++ gas/config/tc-i386.h | 3 +- gas/testsuite/ChangeLog | 9 ++++ gas/testsuite/gas/i386/i386.exp | 2 + gas/testsuite/gas/i386/vmx.d | 25 +++++++++++ gas/testsuite/gas/i386/vmx.s | 21 +++++++++ gas/testsuite/gas/i386/x86-64-vmx.d | 25 +++++++++++ gas/testsuite/gas/i386/x86-64-vmx.s | 21 +++++++++ include/opcode/ChangeLog | 4 ++ include/opcode/i386.h | 14 ++++++ opcodes/ChangeLog | 12 +++++ opcodes/i386-dis.c | 70 ++++++++++++++++++++++++++--- 12 files changed, 204 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/i386/vmx.d create mode 100644 gas/testsuite/gas/i386/vmx.s create mode 100644 gas/testsuite/gas/i386/x86-64-vmx.d create mode 100644 gas/testsuite/gas/i386/x86-64-vmx.s diff --git a/gas/ChangeLog b/gas/ChangeLog index f766ff37c59..58f08226baf 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2007-07-15 H.J. Lu + + * gas/config/tc-i386.h (CpuVMX): New. + (CpuUnknownFlags): Add CpuVMX. + 2005-07-14 Jim Blandy Add support for the Renesas M32C. diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index b10e8874bda..4acf3c1aa40 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -184,6 +184,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 */ @@ -191,7 +192,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 diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 1cb58c900a5..5af722af977 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2007-07-15 H.J. Lu + + * 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. + 2005-07-14 Nick Clifton PR 1063 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 169d552311e..851f6982781 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -60,6 +60,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] 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-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t 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*"] diff --git a/gas/testsuite/gas/i386/vmx.d b/gas/testsuite/gas/i386/vmx.d new file mode 100644 index 00000000000..334702d9c29 --- /dev/null +++ b/gas/testsuite/gas/i386/vmx.d @@ -0,0 +1,25 @@ +#objdump: -dw +#name: i386 VMX + +.*: +file format .* + +Disassembly of section .text: + +0+000 : + 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 + ... diff --git a/gas/testsuite/gas/i386/vmx.s b/gas/testsuite/gas/i386/vmx.s new file mode 100644 index 00000000000..9f52b3fdead --- /dev/null +++ b/gas/testsuite/gas/i386/vmx.s @@ -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 diff --git a/gas/testsuite/gas/i386/x86-64-vmx.d b/gas/testsuite/gas/i386/x86-64-vmx.d new file mode 100644 index 00000000000..201dc059652 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-vmx.d @@ -0,0 +1,25 @@ +#objdump: -dw +#name: 64bit VMX + +.*: +file format .* + +Disassembly of section .text: + +0+000 : + 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 + ... diff --git a/gas/testsuite/gas/i386/x86-64-vmx.s b/gas/testsuite/gas/i386/x86-64-vmx.s new file mode 100644 index 00000000000..7c4018167e4 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-vmx.s @@ -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 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 8690f078a6f..eee00680867 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,7 @@ +2007-07-15 H.J. Lu + + * i386.h (i386_optab): Support Intel VMX Instructions. + 2005-07-10 John David Anglin * hppa.h (pa_opcode): Don't set FLAG_STRICT in pa10 loads and stores. diff --git a/include/opcode/i386.h b/include/opcode/i386.h index 56266a8ccfb..9da7187388c 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -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 } }, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 2d40fabb44a..e6a96f32958 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,15 @@ +2007-07-15 H.J. Lu + + * 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. + 2005-07-14 Jim Blandy Add support for the Renesas M32C and M16C. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 09faa94e721..692562d990f 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -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 *info, bfd_byte *addr) #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 *info, bfd_byte *addr) #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 *info, bfd_byte *addr) #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_twobyte[] = { { "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_modrm[256] = { /* 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); +} -- 2.30.2