diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index d9269bf5c..59d9e0a85 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5138,8 +5138,9 @@ void OpDispatchBuilder::ALUOpImpl(OpcodeArgs, FEXCore::IR::IROps ALUIROp, FEXCor Op->Dest.IsGPR() && Op->Src[SrcIdx].IsGPR() && Op->Dest.Data.GPR == Op->Src[SrcIdx].Data.GPR) { - StoreResult(GPRClass, Op, _Constant(0), -1); - ZeroNZCV(); + auto Result = _Constant(0); + StoreResult(GPRClass, Op, Result, -1); + GenerateFlags_Logical(Op, Result, Result, Result); return; } diff --git a/unittests/ASM/FEX_bugs/xor_flags.asm b/unittests/ASM/FEX_bugs/xor_flags.asm new file mode 100644 index 000000000..c71d2308f --- /dev/null +++ b/unittests/ASM/FEX_bugs/xor_flags.asm @@ -0,0 +1,17 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0x0000000000004600" + } +} +%endif + +; FEX had a bug where an optimization for canonical zeroing of a register would fail to set flags correctly. +; This broke `Metal Gear Rising: Revengeance`. The title screen geometry was broken. + +mov rax, 0 +mov rbx, 0 +sahf +xor rbx, rbx +lahf +hlt