From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: [PATCH 3/8] KVM: x86 emulator: covert SETCC to fastop Date: Thu, 17 Jan 2013 11:42:57 +0200 Message-ID: <20130117094257.GG11529@redhat.com> References: <1358001177-8952-1-git-send-email-avi.kivity@gmail.com> <1358001177-8952-4-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]:40425 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756048Ab3AQJnA (ORCPT ); Thu, 17 Jan 2013 04:43:00 -0500 Content-Disposition: inline In-Reply-To: <1358001177-8952-4-git-send-email-avi.kivity@gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: On Sat, Jan 12, 2013 at 04:32:52PM +0200, Avi Kivity wrote: > This is a bit of a special case since we don't have the usual > byte/word/long/quad switch; instead we switch on the condition code embedded > in the instruction. > > Signed-off-by: Avi Kivity This fails autotest. f9-32 bit guest, but it looks like the failure is in BIOS. > --- > arch/x86/kvm/emulate.c | 60 ++++++++++++++++++++++++-------------------------- > 1 file changed, 29 insertions(+), 31 deletions(-) > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index d641178..f6f615e 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -499,6 +499,28 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) > ON64(FOP3E(op, rax, rbx, cl)) \ > FOP_END > > +/* Special case for SETcc - 1 instruction per cc */ > +#define FOP_SETCC(op) ".align 4; " #op " %al; ret \n\t" > + > +FOP_START(setcc) > +FOP_SETCC(seto) > +FOP_SETCC(setc) > +FOP_SETCC(setz) > +FOP_SETCC(setbe) > +FOP_SETCC(sets) > +FOP_SETCC(setp) > +FOP_SETCC(setl) > +FOP_SETCC(setle) > +FOP_SETCC(setno) > +FOP_SETCC(setnc) > +FOP_SETCC(setnz) > +FOP_SETCC(setnbe) > +FOP_SETCC(setns) > +FOP_SETCC(setnp) > +FOP_SETCC(setnl) > +FOP_SETCC(setnle) > +FOP_END; > + > #define __emulate_1op_rax_rdx(ctxt, _op, _suffix, _ex) \ > do { \ > unsigned long _tmp; \ > @@ -939,39 +961,15 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, > return rc; > } > > -static int test_cc(unsigned int condition, unsigned int flags) > +static u8 test_cc(unsigned int condition, unsigned long flags) > { > - int rc = 0; > + u8 rc; > + void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); > > - switch ((condition & 15) >> 1) { > - case 0: /* o */ > - rc |= (flags & EFLG_OF); > - break; > - case 1: /* b/c/nae */ > - rc |= (flags & EFLG_CF); > - break; > - case 2: /* z/e */ > - rc |= (flags & EFLG_ZF); > - break; > - case 3: /* be/na */ > - rc |= (flags & (EFLG_CF|EFLG_ZF)); > - break; > - case 4: /* s */ > - rc |= (flags & EFLG_SF); > - break; > - case 5: /* p/pe */ > - rc |= (flags & EFLG_PF); > - break; > - case 7: /* le/ng */ > - rc |= (flags & EFLG_ZF); > - /* fall through */ > - case 6: /* l/nge */ > - rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF)); > - break; > - } > - > - /* Odd condition identifiers (lsb == 1) have inverted sense. */ > - return (!!rc ^ (condition & 1)); > + flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF; > + asm("pushq %[flags]; popf; call *%[fastop]" > + : "=a"(rc) : [fastop]"r"(fop), [flags]"r"(flags)); > + return rc; > } > > static void fetch_register_operand(struct operand *op) > -- > 1.8.0.1 -- Gleb.