Re: [PATCH 3/8] KVM: x86 emulator: covert SETCC to fastop

2013-01-17 Thread Gleb Natapov
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 avi.kiv...@gmail.com
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.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/8] KVM: x86 emulator: covert SETCC to fastop

2013-01-12 Thread Avi Kivity
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 avi.kiv...@gmail.com
---
 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

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html