diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 483dec5f0..a85621b89 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -906,11 +906,11 @@ OrderedNode *OpDispatchBuilder::SelectCC(uint8_t OP, OrderedNode *TrueValue, Ord break; } case 0xA: { // JP - Jump if PF == 1 - SrcCond = _Select(FEXCore::IR::COND_NEQ, LoadPF(), ZeroConst, TrueValue, FalseValue); + SrcCond = _Select(FEXCore::IR::COND_EQ, LoadPFInverted(), ZeroConst, TrueValue, FalseValue); break; } case 0xB: { // JNP - Jump if PF == 0 - SrcCond = _Select(FEXCore::IR::COND_EQ, LoadPF(), ZeroConst, TrueValue, FalseValue); + SrcCond = _Select(FEXCore::IR::COND_NEQ, LoadPFInverted(), ZeroConst, TrueValue, FalseValue); break; } case 0xC: { // SF <> OF diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 44f8c4950..ccb77ad25 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -1387,6 +1387,7 @@ private: * @name These functions are used by the deferred flag handling while it is calculating and storing flags in to RFLAGs. * @{ */ OrderedNode *LoadPF(); + OrderedNode *LoadPFInverted(); OrderedNode *LoadAF(); void FixupAF(); void CalculatePF(OrderedNode *Res, OrderedNode *condition = nullptr); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp index 76e1ee533..48d5904de 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Flags.cpp @@ -201,15 +201,10 @@ void OpDispatchBuilder::CalculateOF_Add(uint8_t SrcSize, OrderedNode *Res, Order SetRFLAG(AndOp1); } -OrderedNode *OpDispatchBuilder::LoadPF() { +OrderedNode *OpDispatchBuilder::LoadPFInverted() { // Read the stored byte. This is the original 8-bit result, it needs parity calculated. auto PFByte = GetRFLAG(FEXCore::X86State::RFLAG_PF_LOC); - // We will use the bottom bit of the popcount, set if an odd number of bits are set. - // But the x86 parity flag is supposed to be set for an even number of bits. - // Simply invert any bit of the input GPR and that will invert the bottom bit of the - PFByte = _Xor(OpSize::i32Bit, PFByte, _Constant(1)); - // Cast the input to a 32-bit FPR. Logically we only need 8-bit, but that would // generate unwanted an ubfx instruction. VPopcount will ignore the upper bits anyway. auto InputFPR = _VCastFromGPR(4, 4, PFByte); @@ -222,6 +217,10 @@ OrderedNode *OpDispatchBuilder::LoadPF() { return _And(OpSize::i64Bit, Parity, _Constant(1)); } +OrderedNode *OpDispatchBuilder::LoadPF() { + return _Xor(OpSize::i32Bit, LoadPFInverted(), _Constant(1)); +} + OrderedNode *OpDispatchBuilder::LoadAF() { // Read the stored byte. This is the XOR of the arguments. auto AFByte = GetRFLAG(FEXCore::X86State::RFLAG_AF_LOC);