[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/6] x86emul: extend / amend supported FPU opcodes
First of all there are a number of secondary encodings both Intel and AMD support, but which aren't formally documented. Next there are a few more no-ops - instructions which served a purpose only on 8087 or 287. Further switch from fail_if() to raising of #UD in a couple of places (as the decoding of FPU opcodes should now be complete except where explictly marked as todo). Also adjust a few comments. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -3672,18 +3672,18 @@ x86_emulate( host_and_vcpu_must_have(fpu); switch ( modrm ) { - case 0xc0 ... 0xc7: /* fadd %stN,%stN */ - case 0xc8 ... 0xcf: /* fmul %stN,%stN */ - case 0xd0 ... 0xd7: /* fcom %stN,%stN */ - case 0xd8 ... 0xdf: /* fcomp %stN,%stN */ - case 0xe0 ... 0xe7: /* fsub %stN,%stN */ - case 0xe8 ... 0xef: /* fsubr %stN,%stN */ - case 0xf0 ... 0xf7: /* fdiv %stN,%stN */ - case 0xf8 ... 0xff: /* fdivr %stN,%stN */ + case 0xc0 ... 0xc7: /* fadd %stN,%st */ + case 0xc8 ... 0xcf: /* fmul %stN,%st */ + case 0xd0 ... 0xd7: /* fcom %stN,%st */ + case 0xd8 ... 0xdf: /* fcomp %stN,%st */ + case 0xe0 ... 0xe7: /* fsub %stN,%st */ + case 0xe8 ... 0xef: /* fsubr %stN,%st */ + case 0xf0 ... 0xf7: /* fdiv %stN,%st */ + case 0xf8 ... 0xff: /* fdivr %stN,%st */ emulate_fpu_insn_stub(0xd8, modrm); break; default: - fail_if(modrm >= 0xc0); + ASSERT(ea.type == OP_MEM); ea.bytes = 4; src = ea; if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val, @@ -3729,6 +3729,7 @@ x86_emulate( case 0xc0 ... 0xc7: /* fld %stN */ case 0xc8 ... 0xcf: /* fxch %stN */ case 0xd0: /* fnop */ + case 0xd8 ... 0xdf: /* fstp %stN (alternative encoding) */ case 0xe0: /* fchs */ case 0xe1: /* fabs */ case 0xe4: /* ftst */ @@ -3758,7 +3759,7 @@ x86_emulate( emulate_fpu_insn_stub(0xd9, modrm); break; default: - fail_if(modrm >= 0xc0); + generate_exception_if(ea.type != OP_MEM, EXC_UD); switch ( modrm_reg & 7 ) { case 0: /* fld m32fp */ @@ -3781,7 +3782,8 @@ x86_emulate( dst.type = OP_MEM; emulate_fpu_insn_memdst("fstps", dst.val); break; - /* case 4: fldenv - TODO */ + case 4: /* fldenv - TODO */ + goto cannot_emulate; case 5: /* fldcw m2byte */ ea.bytes = 2; src = ea; @@ -3790,7 +3792,8 @@ x86_emulate( goto done; emulate_fpu_insn_memsrc("fldcw", src.val); break; - /* case 6: fstenv - TODO */ + case 6: /* fnstenv - TODO */ + goto cannot_emulate; case 7: /* fnstcw m2byte */ ea.bytes = 2; dst = ea; @@ -3798,7 +3801,7 @@ x86_emulate( emulate_fpu_insn_memdst("fnstcw", dst.val); break; default: - goto cannot_emulate; + generate_exception_if(true, EXC_UD); } } break; @@ -3818,7 +3821,7 @@ x86_emulate( emulate_fpu_insn_stub(0xda, modrm); break; default: - fail_if(modrm >= 0xc0); + generate_exception_if(ea.type != OP_MEM, EXC_UD); ea.bytes = 4; src = ea; if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val, @@ -3867,16 +3870,16 @@ x86_emulate( vcpu_must_have_cmov(); emulate_fpu_insn_stub_eflags(0xdb, modrm); break; + case 0xe0: /* fneni - 8087 only, ignored by 287 */ + case 0xe1: /* fndisi - 8087 only, ignored by 287 */ case 0xe2: /* fnclex */ - emulate_fpu_insn("fnclex"); - break; case 0xe3: /* fninit */ - emulate_fpu_insn("fninit"); - break; - case 0xe4: /* fsetpm - 287 only, ignored by 387 */ + case 0xe4: /* fnsetpm - 287 only, ignored by 387 */ + /* case 0xe5: frstpm - 287 only, #UD on 387 */ + emulate_fpu_insn_stub(0xdb, modrm); break; default: - fail_if(modrm >= 0xc0); + generate_exception_if(ea.type != OP_MEM, EXC_UD); switch ( modrm_reg & 7 ) { case 0: /* fild m32i */ @@ -3921,7 +3924,7 @@ x86_emulate( emulate_fpu_insn_memdst("fstpt", dst.val); break; default: - goto cannot_emulate; + generate_exception_if(true, EXC_UD); } } break; @@ -3930,16 +3933,18 @@ x86_emulate( host_and_vcpu_must_have(fpu); switch ( modrm ) { - case 0xc0 ... 0xc7: /* fadd %stN */ - case 0xc8 ... 0xcf: /* fmul %stN */ - case 0xe0 ... 0xe7: /* fsubr %stN */ - case 0xe8 ... 0xef: /* fsub %stN */ - case 0xf0 ... 0xf7: /* fdivr %stN */ - case 0xf8 ... 0xff: /* fdiv %stN */ + case 0xc0 ... 0xc7: /* fadd %st,%stN */ + case 0xc8 ... 0xcf: /* fmul %st,%stN */ + case 0xd0 ... 0xd7: /* fcom %stN,%st (alternative encoding) */ + case 0xd8 ... 0xdf: /* fcomp %stN,%st (alternative encoding) */ + case 0xe0 ... 0xe7: /* fsubr %st,%stN */ + case 0xe8 ... 0xef: /* fsub %st,%stN */ + case 0xf0 ... 0xf7: /* fdivr %st,%stN */ + case 0xf8 ... 0xff: /* fdiv %st,%stN */ emulate_fpu_insn_stub(0xdc, modrm); break; default: - fail_if(modrm >= 0xc0); + ASSERT(ea.type == OP_MEM); ea.bytes = 8; src = ea; if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val, @@ -3980,6 +3985,7 @@ x86_emulate( switch ( modrm ) { case 0xc0 ... 0xc7: /* ffree %stN */ + case 0xc8 ... 0xcf: /* fxch %stN (alternative encoding) */ case 0xd0 ... 0xd7: /* fst %stN */ case 0xd8 ... 0xdf: /* fstp %stN */ case 0xe0 ... 0xe7: /* fucom %stN */ @@ -3987,7 +3993,7 @@ x86_emulate( emulate_fpu_insn_stub(0xdd, modrm); break; default: - fail_if(modrm >= 0xc0); + generate_exception_if(ea.type != OP_MEM, EXC_UD); switch ( modrm_reg & 7 ) { case 0: /* fld m64fp */; @@ -4017,6 +4023,9 @@ x86_emulate( dst.type = OP_MEM; emulate_fpu_insn_memdst("fstpl", dst.val); break; + case 4: /* frstor - TODO */ + case 6: /* fnsave - TODO */ + goto cannot_emulate; case 7: /* fnstsw m2byte */ ea.bytes = 2; dst = ea; @@ -4024,7 +4033,7 @@ x86_emulate( emulate_fpu_insn_memdst("fnstsw", dst.val); break; default: - goto cannot_emulate; + generate_exception_if(true, EXC_UD); } } break; @@ -4035,6 +4044,7 @@ x86_emulate( { case 0xc0 ... 0xc7: /* faddp %stN */ case 0xc8 ... 0xcf: /* fmulp %stN */ + case 0xd0 ... 0xd7: /* fcomp %stN (alternative encoding) */ case 0xd9: /* fcompp */ case 0xe0 ... 0xe7: /* fsubrp %stN */ case 0xe8 ... 0xef: /* fsubp %stN */ @@ -4043,7 +4053,7 @@ x86_emulate( emulate_fpu_insn_stub(0xde, modrm); break; default: - fail_if(modrm >= 0xc0); + generate_exception_if(ea.type != OP_MEM, EXC_UD); ea.bytes = 2; src = ea; if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val, @@ -4090,13 +4100,19 @@ x86_emulate( dst.reg = (unsigned long *)&_regs.eax; emulate_fpu_insn_memdst("fnstsw", dst.val); break; + case 0xc0 ... 0xc7: /* ffreep %stN */ case 0xe8 ... 0xef: /* fucomip %stN */ case 0xf0 ... 0xf7: /* fcomip %stN */ vcpu_must_have_cmov(); emulate_fpu_insn_stub_eflags(0xdf, modrm); break; + case 0xc8 ... 0xcf: /* fxch %stN (alternative encoding) */ + case 0xd0 ... 0xd7: /* fstp %stN (alternative encoding) */ + case 0xd8 ... 0xdf: /* fstp %stN (alternative encoding) */ + emulate_fpu_insn_stub(0xdf, modrm); + break; default: - fail_if(modrm >= 0xc0); + generate_exception_if(ea.type != OP_MEM, EXC_UD); switch ( modrm_reg & 7 ) { case 0: /* fild m16i */ Attachment:
x86emul-FPU-opcodes.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |