From 4a9718c8e8dae8f8246db556f1be11e3f646dc52 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Wed, 2 Dec 2020 01:18:28 +0200 Subject: [PATCH 1/2] DFSE: Use uint64_t for flag bitmask, we use up to bit 47 w/ x87 flags --- .../IR/Passes/DeadFlagStoreElimination.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp b/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp index 74078bb46..6aa528533 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,14 @@ 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; + FlagMap[BlockNode].writes = -1UL; } else if (IROp->Op == OP_LOADFLAG) { auto Op = IROp->CW(); - FlagMap[BlockNode].reads |= 1 << Op->Flag; + FlagMap[BlockNode].reads |= 1UL << Op->Flag; } } @@ -98,7 +98,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; } From d7316fe2d013a86e4531f41ecccf065b2c003488 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Wed, 2 Dec 2020 01:39:41 +0200 Subject: [PATCH 2/2] OpDisp, IR: Extend InvalidateFlags to invalidate a bitfield, invalidate PF when not emulated --- .../Interface/Core/OpcodeDispatcher.cpp | 26 +++++++++++++++++-- External/FEXCore/Source/Interface/IR/IR.json | 5 +++- .../IR/Passes/DeadFlagStoreElimination.cpp | 3 ++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 13c184d02..b9b0755f2 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); @@ -4852,6 +4852,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 @@ -4919,6 +4921,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 @@ -4985,6 +4989,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 @@ -5040,6 +5046,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 @@ -5150,6 +5158,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 @@ -5187,6 +5197,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 @@ -5233,6 +5245,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 @@ -5279,6 +5293,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 @@ -5325,6 +5341,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 @@ -5372,6 +5390,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 @@ -5421,6 +5441,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 58fb1072a..93d0697ec 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 6aa528533..6e53b66fc 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/DeadFlagStoreElimination.cpp @@ -43,7 +43,8 @@ bool DeadFlagStoreElimination::Run(IREmitter *IREmit) { FlagMap[BlockNode].writes |= 1UL << Op->Flag; } else if (IROp->Op == OP_INVALIDATEFLAGS) { - FlagMap[BlockNode].writes = -1UL; + auto Op = IROp->CW(); + FlagMap[BlockNode].writes |= Op->Flags; } else if (IROp->Op == OP_LOADFLAG) { auto Op = IROp->CW();