- significantly improve FPU debug print

- update FPU TW before saving FPU state by FNSAVE or FNSTENV
This commit is contained in:
Stanislav Shwartsman 2008-05-05 21:23:33 +00:00
parent 685a10749d
commit f182f11a8e
2 changed files with 55 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: control_w.h,v 1.8 2007-03-23 21:27:12 sshwarts Exp $
// $Id: control_w.h,v 1.9 2008-05-05 21:23:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Stanislav Shwartsman
@ -27,6 +27,10 @@
/* Control Word */
/* ************ */
#define FPU_CW_Reserved_Bits (0xe0c0) /* reserved bits */
#define FPU_CW_Inf (0x1000) /* infinity control, legacy */
#define FPU_CW_RC (0x0C00) /* rounding control */
#define FPU_CW_PC (0x0300) /* precision control */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fpu.cc,v 1.39 2008-04-30 20:41:15 sshwarts Exp $
// $Id: fpu.cc,v 1.40 2008-05-05 21:23:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 Stanislav Shwartsman
@ -84,6 +84,15 @@ void BX_CPU_C::FPU_check_pending_exceptions(void)
int BX_CPU_C::fpu_save_environment(bxInstruction_c *i)
{
/* read all registers in stack order and update x87 tag word */
for(int n=0;n<8;n++) {
// update tag only if it is not empty
if (! IS_TAG_EMPTY(n)) {
int tag = FPU_tagof(BX_READ_FPU_REG(n));
BX_CPU_THIS_PTR the_i387.FPU_settagi(tag, n);
}
}
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
if (protected_mode()) /* Protected Mode */
@ -296,8 +305,9 @@ int BX_CPU_C::fpu_load_environment(bxInstruction_c *i)
}
}
/* always set bit 6 - reserved */
BX_CPU_THIS_PTR the_i387.cwd |= 0x0040;
/* always set bit 6 as '1 */
BX_CPU_THIS_PTR the_i387.cwd =
(BX_CPU_THIS_PTR the_i387.cwd & ~FPU_CW_Reserved_Bits) | 0x0040;
/* check for unmasked exceptions */
if (FPU_PARTIAL_STATUS & ~FPU_CONTROL_WORD & FPU_CW_Exceptions_Mask)
@ -323,7 +333,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLDCW(bxInstruction_c *i)
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit16u cwd = read_virtual_word(i->seg(), RMAddr(i));
FPU_CONTROL_WORD = cwd | 0x0040; // bit 6 is reserved - always set
FPU_CONTROL_WORD = (cwd & ~FPU_CW_Reserved_Bits) | 0x0040; // bit 6 is reserved as '1
/* check for unmasked exceptions */
if (FPU_PARTIAL_STATUS & ~FPU_CONTROL_WORD & FPU_CW_Exceptions_Mask)
@ -461,12 +471,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLDENV(bxInstruction_c *i)
BX_CPU_THIS_PTR prepareFPU(i, CHECK_PENDING_EXCEPTIONS, !UPDATE_LAST_OPCODE);
fpu_load_environment(i);
/* read all registers in stack order */
for(int n=0;n<8;n++)
{
/* read all registers in stack order and update x87 tag word */
for(int n=0;n<8;n++) {
// update tag only if it is not empty
if (! IS_TAG_EMPTY(n))
{
if (! IS_TAG_EMPTY(n)) {
int tag = FPU_tagof(BX_READ_FPU_REG(n));
BX_CPU_THIS_PTR the_i387.FPU_settagi(tag, n);
}
@ -526,13 +534,43 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FPLEGACY(bxInstruction_c *i)
void BX_CPU_C::print_state_FPU(void)
{
static double scale_factor = pow(2.0, -63.0);
static char* cw_round_control[] = {
"NEAREST", "DOWN", "UP", "CHOP"
};
static char* cw_precision_control[] = {
"32", "RES", "64", "80"
};
Bit32u reg;
reg = BX_CPU_THIS_PTR the_i387.get_control_word();
fprintf(stderr, "control word: 0x%04x\n", reg);
fprintf(stderr, "control word: 0x%04x: ", reg);
fprintf(stderr, "%s RC_%s PC_%s %s %s %s %s %s %s\n",
(reg & FPU_CW_Inf) ? "INF" : "inf",
(cw_round_control[(reg & FPU_CW_RC) >> 10]),
(cw_precision_control[(reg & FPU_CW_PC) >> 8]),
(reg & FPU_CW_Precision) ? "PM" : "pm",
(reg & FPU_CW_Underflow) ? "UM" : "um",
(reg & FPU_CW_Overflow) ? "OM" : "om",
(reg & FPU_CW_Zero_Div) ? "ZM" : "zm",
(reg & FPU_CW_Denormal) ? "DM" : "dm",
(reg & FPU_CW_Invalid) ? "IM" : "im");
reg = BX_CPU_THIS_PTR the_i387.get_status_word();
fprintf(stderr, "status word: 0x%04x\n", reg);
fprintf(stderr, " TOS : %d\n", FPU_TOS&7);
fprintf(stderr, "status word: 0x%04x: ", reg);
fprintf(stderr, "%s %s TOS%d %s %s %s %s %s %s %s %s %s %s %s\n",
(reg & FPU_SW_Backward) ? "B" : "b",
(reg & FPU_SW_C3) ? "C3" : "c3", (FPU_TOS&7),
(reg & FPU_SW_C2) ? "C2" : "c2",
(reg & FPU_SW_C1) ? "C1" : "c1",
(reg & FPU_SW_C0) ? "C0" : "c0",
(reg & FPU_SW_Summary) ? "ES" : "es",
(reg & FPU_SW_Stack_Fault) ? "SF" : "sf",
(reg & FPU_SW_Precision) ? "PE" : "pe",
(reg & FPU_SW_Underflow) ? "UE" : "ue",
(reg & FPU_SW_Overflow) ? "OE" : "oe",
(reg & FPU_SW_Zero_Div) ? "ZE" : "ze",
(reg & FPU_SW_Denormal_Op) ? "DE" : "de",
(reg & FPU_SW_Invalid) ? "IE" : "ie");
reg = BX_CPU_THIS_PTR the_i387.get_tag_word();
fprintf(stderr, "tag word: 0x%04x\n", reg);
reg = BX_CPU_THIS_PTR the_i387.foo;