diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index c983ee64e..73a1be308 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -146,7 +146,7 @@ void OpDispatchBuilder::RETOp(OpcodeArgs) { // ABI Optimization: Flags don't survive calls or rets if (CTX->Config.ABILocalFlags) { - _InvalidateFlags(); + _InvalidateFlags(~0UL); // all flags } auto Constant = _Constant(GPRSize); @@ -630,7 +630,7 @@ void OpDispatchBuilder::CALLOp(OpcodeArgs) { // ABI Optimization: Flags don't survive calls or rets if (CTX->Config.ABILocalFlags) { - _InvalidateFlags(); + _InvalidateFlags(~0UL); // all flags } auto ConstantPC = _Constant(Op->PC + Op->InstSize); @@ -4857,6 +4857,8 @@ void OpDispatchBuilder::GenerateFlags_ADC(FEXCore::X86Tables::DecodedOp Op, Orde auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // ZF @@ -4924,6 +4926,8 @@ void OpDispatchBuilder::GenerateFlags_SBB(FEXCore::X86Tables::DecodedOp Op, Orde auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // ZF @@ -4990,6 +4994,8 @@ void OpDispatchBuilder::GenerateFlags_SUB(FEXCore::X86Tables::DecodedOp Op, Orde auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // ZF @@ -5045,6 +5051,8 @@ void OpDispatchBuilder::GenerateFlags_ADD(FEXCore::X86Tables::DecodedOp Op, Orde auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // ZF @@ -5155,6 +5163,8 @@ void OpDispatchBuilder::GenerateFlags_Logical(FEXCore::X86Tables::DecodedOp Op, auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // ZF @@ -5192,6 +5202,8 @@ void OpDispatchBuilder::GenerateFlags_ShiftLeft(FEXCore::X86Tables::DecodedOp Op auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); COND_FLAG_SET(Src2, RFLAG_PF_LOC, XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // AF @@ -5238,6 +5250,8 @@ void OpDispatchBuilder::GenerateFlags_ShiftRight(FEXCore::X86Tables::DecodedOp O auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); COND_FLAG_SET(Src2, RFLAG_PF_LOC, XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // AF @@ -5284,6 +5298,8 @@ void OpDispatchBuilder::GenerateFlags_SignShiftRight(FEXCore::X86Tables::Decoded auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); COND_FLAG_SET(Src2, RFLAG_PF_LOC, XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // AF @@ -5330,6 +5346,8 @@ void OpDispatchBuilder::GenerateFlags_ShiftLeftImmediate(FEXCore::X86Tables::Dec auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // AF @@ -5377,6 +5395,8 @@ void OpDispatchBuilder::GenerateFlags_SignShiftRightImmediate(FEXCore::X86Tables auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // AF @@ -5426,6 +5446,8 @@ void OpDispatchBuilder::GenerateFlags_ShiftRightImmediate(FEXCore::X86Tables::De auto PopCountOp = _Popcount(_And(Res, EightBitMask)); auto XorOp = _Xor(PopCountOp, _Constant(1)); SetRFLAG(XorOp); + } else { + _InvalidateFlags(1UL << FEXCore::X86State::RFLAG_PF_LOC); } // AF diff --git a/External/FEXCore/Source/Interface/IR/IR.json b/External/FEXCore/Source/Interface/IR/IR.json index 71ba1c55f..55c711c6c 100644 --- a/External/FEXCore/Source/Interface/IR/IR.json +++ b/External/FEXCore/Source/Interface/IR/IR.json @@ -95,7 +95,10 @@ "InvalidateFlags": { "OpClass": "Misc", - "HasSideEffects": true + "HasSideEffects": true, + "Args": [ + "uint64_t", "Flags" + ] }, "EndBlock": { diff --git a/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp b/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp index 74078bb46..6e53b66fc 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp @@ -9,9 +9,9 @@ public: }; struct FlagInfo { - uint32_t reads { 0 }; - uint32_t writes { 0 }; - uint32_t kill { 0 }; + uint64_t reads { 0 }; + uint64_t writes { 0 }; + uint64_t kill { 0 }; }; /** @@ -40,14 +40,15 @@ bool DeadFlagStoreElimination::Run(IREmitter *IREmit) { if (IROp->Op == OP_STOREFLAG) { auto Op = IROp->CW(); - FlagMap[BlockNode].writes |= 1 << Op->Flag; + FlagMap[BlockNode].writes |= 1UL << Op->Flag; } else if (IROp->Op == OP_INVALIDATEFLAGS) { - FlagMap[BlockNode].writes = -1; + auto Op = IROp->CW(); + FlagMap[BlockNode].writes |= Op->Flags; } else if (IROp->Op == OP_LOADFLAG) { auto Op = IROp->CW(); - FlagMap[BlockNode].reads |= 1 << Op->Flag; + FlagMap[BlockNode].reads |= 1UL << Op->Flag; } } @@ -98,7 +99,7 @@ bool DeadFlagStoreElimination::Run(IREmitter *IREmit) { if (IROp->Op == OP_STOREFLAG) { auto Op = IROp->CW(); // If this StoreFlag is never read, remove it - if (FlagMap[BlockNode].kill & (1 << Op->Flag)) { + if (FlagMap[BlockNode].kill & (1UL << Op->Flag)) { IREmit->Remove(CodeNode); Changed = true; }