From mboxrd@z Thu Jan 1 00:00:00 1970 From: Guillaume Thouvenin Subject: [PATCH] x86 emulator: Add Src2 decode set Date: Thu, 9 Oct 2008 09:52:53 +0200 Message-ID: <20081009095253.66737bf1@frecb000711> References: <20081008145245.78c7084d@frecb000711> <48ECC028.5070807@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: Avi Kivity To: kvm Return-path: Received: from ecfrec.frec.bull.fr ([129.183.4.8]:42482 "EHLO ecfrec.frec.bull.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751272AbYJIHxf (ORCPT ); Thu, 9 Oct 2008 03:53:35 -0400 In-Reply-To: <48ECC028.5070807@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: Instruction like shld has three operands, so we need to add a Src2 decode set. We start with Src2None, Src2CL, and Src2Imm8 to support shld and we will expand it later. Signed-off-by: Guillaume Thouvenin --- arch/x86/kvm/x86_emulate.c | 47 ++++++++++++++++++++++++++++---------- include/asm-x86/kvm_x86_emulate.h | 1 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index a391e21..c9ef2da 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -59,16 +59,21 @@ #define SrcImm (5<<4) /* Immediate operand. */ #define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ #define SrcMask (7<<4) +/* Source 2 operand type */ +#define Src2None (0<<7) +#define Src2CL (1<<7) +#define Src2Imm8 (2<<7) +#define Src2Mask (7<<7) /* Generic ModRM decode. */ -#define ModRM (1<<7) +#define ModRM (1<<24) /* Destination is only written; never read. */ -#define Mov (1<<8) -#define BitOp (1<<9) -#define MemAbs (1<<10) /* Memory operand is absolute displacement */ -#define String (1<<12) /* String instruction (rep capable) */ -#define Stack (1<<13) /* Stack instruction (push/pop) */ -#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ -#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ +#define Mov (1<<25) +#define BitOp (1<<26) +#define MemAbs (1<<27) /* Memory operand is absolute displacement */ +#define String (1<<28) /* String instruction (rep capable) */ +#define Stack (1<<29) /* Stack instruction (push/pop) */ +#define Group (1<<30) /* Bits 3:5 of modrm byte extend opcode */ +#define GroupDual (1<<31) /* Alternate decoding of mod == 3 */ #define GroupMask 0xff /* Group number stored in bits 0:7 */ enum { @@ -76,7 +81,7 @@ enum { Group1A, Group3_Byte, Group3, Group4, Group5, Group7, }; -static u16 opcode_table[256] = { +static u32 opcode_table[256] = { /* 0x00 - 0x07 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, @@ -195,7 +200,7 @@ static u16 opcode_table[256] = { ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, }; -static u16 twobyte_table[256] = { +static u32 twobyte_table[256] = { /* 0x00 - 0x0F */ 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, @@ -253,7 +258,7 @@ static u16 twobyte_table[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static u16 group_table[] = { +static u32 group_table[] = { [Group1_80*8] = ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, @@ -297,7 +302,7 @@ static u16 group_table[] = { SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, }; -static u16 group2_table[] = { +static u32 group2_table[] = { [Group7*8] = SrcNone | ModRM, 0, 0, 0, SrcNone | ModRM | DstMem | Mov, 0, @@ -1043,6 +1048,24 @@ done_prefixes: break; } + /* + * Decode and fetch the second source operand: register, memory + * or immediate. + */ + switch (c->d & Src2Mask) { + case Src2None: + break; + case Src2CL: + c->src2.val = c->regs[VCPU_REGS_RCX]; + break; + case Src2Imm8: + c->src2.type = OP_IMM; + c->src2.ptr = (unsigned long *)c->eip; + c->src2.bytes = 1; + c->src2.val = insn_fetch(u8, 1, c->eip); + break; + } + /* Decode and fetch the destination operand: register or memory. */ switch (c->d & DstMask) { case ImplicitOps: diff --git a/include/asm-x86/kvm_x86_emulate.h b/include/asm-x86/kvm_x86_emulate.h index 4e8c1e4..00de896 100644 --- a/include/asm-x86/kvm_x86_emulate.h +++ b/include/asm-x86/kvm_x86_emulate.h @@ -123,6 +123,7 @@ struct decode_cache { u8 ad_bytes; u8 rex_prefix; struct operand src; + struct operand src2; struct operand dst; bool has_seg_override; u8 seg_override;