diff -uNr xen-unstable.hg/xen/arch/x86/x86_emulate.c xen-unstable.hg-patched/xen/arch/x86/x86_emulate.c --- xen-unstable.hg/xen/arch/x86/x86_emulate.c 2008-02-27 09:53:48.219043994 +0100 +++ xen-unstable.hg-patched/xen/arch/x86/x86_emulate.c 2008-02-29 23:09:48.858727693 +0100 @@ -127,7 +127,7 @@ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x98 - 0x9F */ - ImplicitOps, ImplicitOps, ImplicitOps, 0, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0xA0 - 0xA7 */ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, @@ -160,7 +160,7 @@ ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0xD8 - 0xDF */ - 0, ImplicitOps|ModRM, 0, ImplicitOps|ModRM, 0, ImplicitOps|ModRM, 0, 0, + 0, ImplicitOps|ModRM, 0, ImplicitOps|ModRM, 0, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, /* 0xE0 - 0xE7 */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, @@ -2355,6 +2355,10 @@ break; } + case 0x9b: /* wait/fwait */ + /* No-op */ + break; + case 0x9c: /* pushf */ src.val = _regs.eflags; goto push; @@ -2670,12 +2674,28 @@ case 0xd9: /* FPU 0xd9 */ fail_if(ops->load_fpu_ctxt == NULL); ops->load_fpu_ctxt(ctxt); - fail_if((modrm_reg & 7) != 7); - fail_if(modrm >= 0xc0); - /* fnstcw m2byte */ - ea.bytes = 2; - dst = ea; - asm volatile ( "fnstcw %0" : "=m" (dst.val) ); + switch ( modrm ) + { + case 0xc0: + asm volatile ( "fld %st(0)" ); + break; + case 0xe0: + asm volatile ( "fchs" ); + break; + case 0xe8: + asm volatile ( "fld1" ); + break; + case 0xee: + asm volatile ( "fldz" ); + break; + default: + fail_if((modrm_reg & 7) != 7); + fail_if(modrm >= 0xc0); + /* fnstcw m2byte */ + ea.bytes = 2; + dst = ea; + asm volatile ( "fnstcw %0" : "=m" (dst.val) ); + } break; case 0xdb: /* FPU 0xdb */ @@ -2697,6 +2717,34 @@ asm volatile ( "fnstsw %0" : "=m" (dst.val) ); break; + case 0xde: /* FPU 0xde */ + fail_if(ops->load_fpu_ctxt == NULL); + ops->load_fpu_ctxt(ctxt); + switch ( modrm ) + { + case 0xd9: + asm volatile ( "fcompp" ); + break; + case 0xf9: + asm volatile ( "fdivp %st(1),%st" ); + break; + default: + goto cannot_emulate; + } + break; + + + case 0xdf: /* FPU 0xdf */ + fail_if(ops->load_fpu_ctxt == NULL); + ops->load_fpu_ctxt(ctxt); + fail_if(modrm != 0xe0); + /* fnstsw %ax */ + dst.bytes = 2; + dst.type = OP_REG; + dst.reg = (unsigned long *)&_regs.eax; + asm volatile ( "fnstsw %0" : "=m" (dst.val) ); + break; + case 0xe0 ... 0xe2: /* loop{,z,nz} */ { int rel = insn_fetch_type(int8_t); int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */