Fixed unmasked exception response for x87 floating point compare instructions

This commit is contained in:
Stanislav Shwartsman 2009-04-12 22:07:59 +00:00
parent 7278e563a8
commit 8af32cb637

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fpu_compare.cc,v 1.21 2009-03-10 21:43:11 sshwarts Exp $
// $Id: fpu_compare.cc,v 1.22 2009-04-12 22:07:59 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 Stanislav Shwartsman
@ -92,11 +92,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_STi(bxInstruction_c *i)
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm()))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -107,9 +106,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_STi(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -130,11 +129,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOMI_ST0_STj(bxInstruction_c *i)
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm()))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -145,9 +143,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOMI_ST0_STj(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status);
BX_CPU_THIS_PTR write_eflags_fpu_compare(rc);
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
BX_CPU_THIS_PTR write_eflags_fpu_compare(rc);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -169,11 +167,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMI_ST0_STj(bxInstruction_c *i)
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm()))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -184,9 +181,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMI_ST0_STj(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status);
BX_CPU_THIS_PTR write_eflags_fpu_compare(rc);
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
BX_CPU_THIS_PTR write_eflags_fpu_compare(rc);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -206,11 +203,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOM_STi(bxInstruction_c *i)
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm()))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -221,9 +217,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOM_STi(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -246,11 +242,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_SINGLE_REAL(bxInstruction_c *i)
if (IS_TAG_EMPTY(0))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -261,10 +256,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_SINGLE_REAL(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0),
float32_to_floatx80(load_reg, status), status);
float32_to_floatx80(load_reg, status), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -287,11 +282,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_DOUBLE_REAL(bxInstruction_c *i)
if (IS_TAG_EMPTY(0))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -302,10 +296,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_DOUBLE_REAL(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0),
float64_to_floatx80(load_reg, status), status);
float64_to_floatx80(load_reg, status), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -328,11 +322,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_WORD_INTEGER(bxInstruction_c *i)
if (IS_TAG_EMPTY(0))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -343,10 +336,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_WORD_INTEGER(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0),
int32_to_floatx80((Bit32s)(load_reg)), status);
int32_to_floatx80((Bit32s)(load_reg)), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -369,11 +362,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_DWORD_INTEGER(bxInstruction_c *i)
if (IS_TAG_EMPTY(0))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -384,9 +376,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_DWORD_INTEGER(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), int32_to_floatx80(load_reg), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
if (pop_stack)
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -406,12 +398,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOMPP(bxInstruction_c *i)
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
BX_CPU_THIS_PTR the_i387.FPU_pop();
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -422,9 +412,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOMPP(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
BX_CPU_THIS_PTR the_i387.FPU_pop();
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -442,12 +432,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMPP(bxInstruction_c *i)
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
BX_CPU_THIS_PTR the_i387.FPU_pop();
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -458,9 +446,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMPP(bxInstruction_c *i)
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status);
setcc(status_word_flags_fpu_compare(rc));
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) {
setcc(status_word_flags_fpu_compare(rc));
BX_CPU_THIS_PTR the_i387.FPU_pop();
BX_CPU_THIS_PTR the_i387.FPU_pop();
}
@ -512,27 +500,20 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FTST(bxInstruction_c *i)
clear_C1();
if (IS_TAG_EMPTY(0))
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* the masked response */
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
}
return;
if (IS_TAG_EMPTY(0)) {
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3);
}
else {
extern const floatx80 Const_Z;
extern const floatx80 Const_Z;
float_status_t status =
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
float_status_t status =
FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), Const_Z, status);
if (! BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags))
int rc = floatx80_compare(BX_READ_FPU_REG(0), Const_Z, status);
setcc(status_word_flags_fpu_compare(rc));
BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags);
}
#else
BX_INFO(("FTST: required FPU, configure --enable-fpu"));
#endif