From 8af32cb6374fbde3b2641f8d2a64659ae417d0bc Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Sun, 12 Apr 2009 22:07:59 +0000 Subject: [PATCH] Fixed unmasked exception response for x87 floating point compare instructions --- bochs/fpu/fpu_compare.cc | 87 ++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 53 deletions(-) diff --git a/bochs/fpu/fpu_compare.cc b/bochs/fpu/fpu_compare.cc index df0441c3f..4bedaa901 100755 --- a/bochs/fpu/fpu_compare.cc +++ b/bochs/fpu/fpu_compare.cc @@ -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