diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index b204d7d6d..781a8fbfc 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -742,15 +742,13 @@ void OpDispatchBuilder::CondJUMPOp(OpcodeArgs) { auto CurrentBlock = GetCurrentBlock(); - // Fallback { IRPair CondJump_; - auto [Complex, SimpleCond] = DecodeNZCVCondition(Op->OP & 0xF); + auto OP = Op->OP & 0xF; + auto [Complex, SimpleCond] = DecodeNZCVCondition(OP); if (Complex) { - auto TakeBranch = _Constant(1); - auto DoNotTakeBranch = _Constant(0); - auto SrcCond = SelectCC(Op->OP & 0xF, OpSize::i64Bit, TakeBranch, DoNotTakeBranch); - CondJump_ = CondJump(SrcCond); + LOGMAN_THROW_AA_FMT(OP == 0xA || OP == 0xB, "only PF left"); + CondJump_ = CondJumpBit(LoadPFRaw(false), 0, OP == 0xB); } else { CondJump_ = CondJumpNZCV(SimpleCond); } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 3b894492b..067fcbb7b 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -4,6 +4,7 @@ #include "Interface/Core/Frontend.h" #include "Interface/Core/X86Tables/X86Tables.h" #include "Interface/Context/Context.h" +#include "Interface/IR/IR.h" #include "Interface/IR/IREmitter.h" #include @@ -156,6 +157,11 @@ public: auto Placeholder = _InlineConstant(0); return _CondJump(Placeholder, Placeholder, InvalidNode, InvalidNode, Cond, 0, true); } + IRPair CondJumpBit(Ref Src, unsigned Bit, bool Set) { + FlushRegisterCache(); + auto InlineConst = _InlineConstant(Bit); + return _CondJump(Src, InlineConst, InvalidNode, InvalidNode, {Set ? COND_TSTNZ : COND_TSTZ}, 0, false); + } IRPair ExitFunction(Ref NewRIP) { FlushRegisterCache(); return _ExitFunction(NewRIP);