From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: [PATCH 2/8] KVM: x86 emulator: decode extended accumulator explicity Date: Sun, 10 Feb 2013 14:19:29 +0200 Message-ID: <20130210121929.GQ7837@redhat.com> References: <1360402311-19904-1-git-send-email-avi.kivity@gmail.com> <1360402311-19904-3-git-send-email-avi.kivity@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Marcelo Tosatti , kvm@vger.kernel.org To: Avi Kivity Return-path: Received: from mx1.redhat.com ([209.132.183.28]:48464 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754193Ab3BJMTc (ORCPT ); Sun, 10 Feb 2013 07:19:32 -0500 Content-Disposition: inline In-Reply-To: <1360402311-19904-3-git-send-email-avi.kivity@gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: On Sat, Feb 09, 2013 at 11:31:45AM +0200, Avi Kivity wrote: > Single-operand MUL and DIV access an extended accumulator: AX for byte > instructions, and DX:AX, EDX:EAX, or RDX:RAX for larger-sized instructions. > Add support for fetching the extended accumulator. > Where this "extended accumulator" definition is coming from? Spec just says that two registers are used for a result depending on the operand size. > In order not to change things too much, RDX is loaded into Src2, which is > already loaded by fastop(). This avoids increasing register pressure on > i386. > > Signed-off-by: Avi Kivity > --- > arch/x86/kvm/emulate.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index 18c86b5..aa8516e 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -60,6 +60,8 @@ > #define OpGS 25ull /* GS */ > #define OpMem8 26ull /* 8-bit zero extended memory operand */ > #define OpImm64 27ull /* Sign extended 16/32/64-bit immediate */ > +#define OpAccLo 29ull /* Low part of extended acc (AX/AX/EAX/RAX) */ > +#define OpAccHi 30ull /* High part of extended acc (-/DX/EDX/RDX) */ > > #define OpBits 5 /* Width of operand field */ > #define OpMask ((1ull << OpBits) - 1) > @@ -85,6 +87,7 @@ > #define DstMem64 (OpMem64 << DstShift) > #define DstImmUByte (OpImmUByte << DstShift) > #define DstDX (OpDX << DstShift) > +#define DstAccLo (OpAccLo << DstShift) > #define DstMask (OpMask << DstShift) > /* Source operand type. */ > #define SrcShift 6 > @@ -106,6 +109,7 @@ > #define SrcImm64 (OpImm64 << SrcShift) > #define SrcDX (OpDX << SrcShift) > #define SrcMem8 (OpMem8 << SrcShift) > +#define SrcAccHi (OpAccHi << SrcShift) > #define SrcMask (OpMask << SrcShift) > #define BitOp (1<<11) > #define MemAbs (1<<12) /* Memory operand is absolute displacement */ > @@ -154,6 +158,8 @@ > #define NoWrite ((u64)1 << 45) /* No writeback */ > #define SrcWrite ((u64)1 << 46) /* Write back src operand */ > > +#define DstXacc (DstAccLo | SrcAccHi | SrcWrite) > + > #define X2(x...) x, x > #define X3(x...) X2(x), x > #define X4(x...) X2(x), X2(x) > @@ -4129,6 +4135,22 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, > fetch_register_operand(op); > op->orig_val = op->val; > break; > + case OpAccLo: > + op->type = OP_REG; > + op->bytes = (ctxt->d & ByteOp) ? 2 : ctxt->op_bytes; > + op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX); > + fetch_register_operand(op); > + op->orig_val = op->val; > + break; > + case OpAccHi: > + if (ctxt->d & ByteOp) > + break; Why would we set OpAccHi if ByteOp is set in decode tables in the first place? > + op->type = OP_REG; > + op->bytes = ctxt->op_bytes; > + op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX); > + fetch_register_operand(op); > + op->orig_val = op->val; > + break; > case OpDI: > op->type = OP_MEM; > op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; > -- > 1.8.1.2 -- Gleb.