Fixes for x87 restore by FXRSTOR/XRSTOR

This commit is contained in:
Stanislav Shwartsman 2009-10-27 20:03:35 +00:00
parent 5ab53ac4b0
commit 234770395d
3 changed files with 37 additions and 16 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: sse_move.cc,v 1.101 2009-10-24 11:17:51 sshwarts Exp $
// $Id: sse_move.cc,v 1.102 2009-10-27 20:03:35 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003-2009 Stanislav Shwartsman
@ -358,6 +358,16 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FXRSTOR(bxInstruction_c *i)
BX_CPU_THIS_PTR the_i387.twd = unpack_FPU_TW(tag_byte);
/* check for unmasked exceptions */
if (FPU_PARTIAL_STATUS & ~FPU_CONTROL_WORD & FPU_CW_Exceptions_Mask) {
/* set the B and ES bits in the status-word */
FPU_PARTIAL_STATUS |= FPU_SW_Summary | FPU_SW_Backward;
}
else {
/* clear the B and ES bits in the status-word */
FPU_PARTIAL_STATUS &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR efer.get_FFXSR() && CPL == 0 && Is64BitMode())
return; // skip restore of the XMM state

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: xsave.cc,v 1.21 2009-10-27 18:30:13 sshwarts Exp $
// $Id: xsave.cc,v 1.22 2009-10-27 20:03:35 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008-2009 Stanislav Shwartsman
@ -56,6 +56,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
// We will go feature-by-feature and not run over all XCR0 bits
//
Bit64u header1 = read_virtual_qword(i->seg(), eaddr + 512);
/////////////////////////////////////////////////////////////////////////////
if (BX_CPU_THIS_PTR xcr0.get_FPU() && (EAX & BX_XCR0_FPU_MASK) != 0)
{
@ -123,6 +125,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
write_virtual_dqword(i->seg(), eaddr+index*16+32, (Bit8u *) &xmm);
}
header1 |= BX_XCR0_FPU_MASK;
}
/////////////////////////////////////////////////////////////////////////////
@ -140,9 +144,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
eaddr+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
}
}
header1 |= BX_XCR0_SSE_MASK;
}
// skip header update for now, required to know if a CPU feature is in its initial state
// always update header to 'dirty' state
write_virtual_qword(i->seg(), eaddr + 512, header1);
#else
BX_INFO(("XSAVE: required XSAVE support, use --enable-xsave option"));
exception(BX_UD_EXCEPTION, 0, 0);
@ -242,6 +249,16 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
/* Restore floating point tag word - see desription for FXRSTOR instruction */
BX_CPU_THIS_PTR the_i387.twd = unpack_FPU_TW(tag_byte);
/* check for unmasked exceptions */
if (FPU_PARTIAL_STATUS & ~FPU_CONTROL_WORD & FPU_CW_Exceptions_Mask) {
/* set the B and ES bits in the status-word */
FPU_PARTIAL_STATUS |= FPU_SW_Summary | FPU_SW_Backward;
}
else {
/* clear the B and ES bits in the status-word */
FPU_PARTIAL_STATUS &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
}
else {
// initialize FPU with reset values
@ -318,17 +335,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XGETBV(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSETBV(bxInstruction_c *i)
{
#if BX_SUPPORT_XSAVE
if (v8086_mode()) {
BX_ERROR(("XSETBV: not recognized in virtual-8086 mode"));
exception(BX_UD_EXCEPTION, 0, 0);
}
if(! (BX_CPU_THIS_PTR cr4.get_OSXSAVE())) {
BX_ERROR(("XSETBV: OSXSAVE feature is not enabled in CR4!"));
exception(BX_UD_EXCEPTION, 0, 0);
}
if (CPL != 0) {
if (v8086_mode() || CPL != 0) {
BX_ERROR(("XSETBV: The current priveledge level is not 0"));
exception(BX_GP_EXCEPTION, 0, 0);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fpu.cc,v 1.57 2009-10-14 20:45:29 sshwarts Exp $
// $Id: fpu.cc,v 1.58 2009-10-27 20:03:35 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003-2009 Stanislav Shwartsman
@ -312,8 +312,7 @@ bx_address BX_CPU_C::fpu_load_environment(bxInstruction_c *i)
/* set the B and ES bits in the status-word */
FPU_PARTIAL_STATUS |= FPU_SW_Summary | FPU_SW_Backward;
}
else
{
else {
/* clear the B and ES bits in the status-word */
FPU_PARTIAL_STATUS &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
@ -582,12 +581,12 @@ void BX_CPU_C::print_state_FPU(void)
fprintf(stderr, "tag word: 0x%04x\n", reg);
reg = BX_CPU_THIS_PTR the_i387.foo;
fprintf(stderr, "operand: 0x%04x\n", reg);
reg = (Bit32u)(BX_CPU_THIS_PTR the_i387.fip) & 0xffffffff;
fprintf(stderr, "fip: 0x%08x\n", reg);
fprintf(stderr, "fip: 0x" FMT_ADDRX "\n",
BX_CPU_THIS_PTR the_i387.fip);
reg = BX_CPU_THIS_PTR the_i387.fcs;
fprintf(stderr, "fcs: 0x%04x\n", reg);
reg = (Bit32u)(BX_CPU_THIS_PTR the_i387.fdp) & 0xffffffff;
fprintf(stderr, "fdp: 0x%08x\n", reg);
fprintf(stderr, "fdp: 0x" FMT_ADDRX "\n",
BX_CPU_THIS_PTR the_i387.fdp);
reg = BX_CPU_THIS_PTR the_i387.fds;
fprintf(stderr, "fds: 0x%04x\n", reg);