diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 857eb3e72..b6011b088 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -745,7 +745,7 @@ public: void X87FLDCW(OpcodeArgs); void X87FNSAVE(OpcodeArgs); void X87FNSTENV(OpcodeArgs); - void X87FNSTSW(OpcodeArgs); + void X87FNSTSW(OpcodeArgs, bool DestRAX); void X87FRSTOR(OpcodeArgs); void X87FSTCW(OpcodeArgs); void X87FXAM(OpcodeArgs); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp index b04f47e6f..d8820abd5 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp @@ -768,10 +768,14 @@ Ref OpDispatchBuilder::ReconstructFSW_Helper(Ref T) { // Store Status Word // There's no load Status Word instruction but you can load it through frstor // or fldenv. -void OpDispatchBuilder::X87FNSTSW(OpcodeArgs) { +void OpDispatchBuilder::X87FNSTSW(OpcodeArgs, bool DestRAX) { Ref TopValue = _SyncStackToSlow(); Ref StatusWord = ReconstructFSW_Helper(TopValue); - StoreResultGPR(Op, StatusWord); + if (DestRAX) { + StoreGPRRegister(X86State::REG_RAX, StatusWord, OpSize::i16Bit); + } else { + StoreResultGPR(Op, StatusWord); + } } void OpDispatchBuilder::FNCLEX(OpcodeArgs) { diff --git a/FEXCore/Source/Interface/Core/X86Tables/X87Tables.cpp b/FEXCore/Source/Interface/Core/X86Tables/X87Tables.cpp index 286f9f575..5d2dff353 100644 --- a/FEXCore/Source/Interface/Core/X86Tables/X87Tables.cpp +++ b/FEXCore/Source/Interface/Core/X86Tables/X87Tables.cpp @@ -216,7 +216,7 @@ constexpr std::array X87F64OpTable = {{ // 5 = Invalid {OPDReg(0xDD, 6) | 0x00, 8, &OpDispatchBuilder::X87FNSAVE}, - {OPDReg(0xDD, 7) | 0x00, 8, &OpDispatchBuilder::X87FNSTSW}, + {OPDReg(0xDD, 7) | 0x00, 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::X87FNSTSW, false>}, {OPD(0xDD, 0xC0), 8, &OpDispatchBuilder::X87FFREE}, {OPD(0xDD, 0xC8), 8, &OpDispatchBuilder::FXCH}, @@ -284,7 +284,7 @@ constexpr std::array X87F64OpTable = {{ {OPD(0xDF, 0xD0), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::FSTToStack>}, {OPD(0xDF, 0xD8), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::FSTToStack>}, - {OPD(0xDF, 0xE0), 8, &OpDispatchBuilder::X87FNSTSW}, + {OPD(0xDF, 0xE0), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::X87FNSTSW, true>}, {OPD(0xDF, 0xE8), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::FCOMIF64, OpSize::f80Bit, false, OpDispatchBuilder::FCOMIFlags::FLAGS_RFLAGS, false>}, {OPD(0xDF, 0xF0), 8, @@ -483,7 +483,7 @@ constexpr std::array X87F80OpTable = {{ // 5 = Invalid {OPDReg(0xDD, 6) | 0x00, 8, &OpDispatchBuilder::X87FNSAVE}, - {OPDReg(0xDD, 7) | 0x00, 8, &OpDispatchBuilder::X87FNSTSW}, + {OPDReg(0xDD, 7) | 0x00, 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::X87FNSTSW, false>}, {OPD(0xDD, 0xC0), 8, &OpDispatchBuilder::X87FFREE}, {OPD(0xDD, 0xC8), 8, &OpDispatchBuilder::FXCH}, @@ -545,7 +545,7 @@ constexpr std::array X87F80OpTable = {{ {OPD(0xDF, 0xD0), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::FSTToStack>}, {OPD(0xDF, 0xD8), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::FSTToStack>}, - {OPD(0xDF, 0xE0), 8, &OpDispatchBuilder::X87FNSTSW}, + {OPD(0xDF, 0xE0), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::X87FNSTSW, true>}, {OPD(0xDF, 0xE8), 8, &OpDispatchBuilder::Bind<&OpDispatchBuilder::FCOMI, OpSize::f80Bit, false, OpDispatchBuilder::FCOMIFlags::FLAGS_RFLAGS, false>}, {OPD(0xDF, 0xF0), 8, @@ -794,7 +794,7 @@ auto GenerateX87TableLambda = [](const auto DispatchTable) consteval { // / 3 {OPD(0xDF, 0xD8), 8, X86InstInfo{"FSTP", TYPE_X87, FLAGS_SF_MOD_DST | FLAGS_POP, 0}}, // / 4 - {OPD(0xDF, 0xE0), 1, X86InstInfo{"FNSTSW", TYPE_INST, GenFlagsSameSize(SIZE_16BIT) | FLAGS_SF_DST_RAX, 0}}, + {OPD(0xDF, 0xE0), 1, X86InstInfo{"FNSTSW", TYPE_INST, GenFlagsSameSize(SIZE_16BIT), 0}}, {OPD(0xDF, 0xE1), 7, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0}}, // / 5 {OPD(0xDF, 0xE8), 8, X86InstInfo{"FUCOMIP", TYPE_INST, FLAGS_POP, 0}},