diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 006a6df8e..6f9f2ba49 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -1559,18 +1559,23 @@ void OpDispatchBuilder::LAHFOp(OpcodeArgs) { } void OpDispatchBuilder::FLAGControlOp(OpcodeArgs) { + // Calculate flags early. + CalculateDeferredFlags(); + enum class OpType { Clear, Set, - Complement, }; OpType Type; uint64_t Flag; switch (Op->OP) { - case 0xF5: // CMC - Flag= FEXCore::X86State::RFLAG_CF_LOC; - Type = OpType::Complement; - break; + case 0xF5: {// CMC + uint32_t Bit = 1u << IndexNZCV(X86State::RFLAG_CF_LOC); + SetNZCV(_Xor(OpSize::i32Bit, GetNZCV(), _Constant(Bit))); + PossiblySetNZCVBits |= Bit; + return; + } + case 0xF8: // CLC Flag= FEXCore::X86State::RFLAG_CF_LOC; Type = OpType::Clear; @@ -1593,9 +1598,6 @@ void OpDispatchBuilder::FLAGControlOp(OpcodeArgs) { LOGMAN_THROW_AA_FMT(Flag != FEXCore::X86State::RFLAG_AF_LOC, "No AF complement instruction in x86"); - // Calculate flags early. - CalculateDeferredFlags(); - OrderedNode *Result{}; switch (Type) { case OpType::Clear: { @@ -1606,11 +1608,6 @@ void OpDispatchBuilder::FLAGControlOp(OpcodeArgs) { Result = _Constant(1); break; } - case OpType::Complement: { - auto RFLAG = GetRFLAG(Flag); - Result = _Xor(OpSize::i64Bit, RFLAG, _Constant(1)); - break; - } } SetRFLAG(Result, Flag); diff --git a/unittests/InstructionCountCI/Primary.json b/unittests/InstructionCountCI/Primary.json index d7aea93e6..f988a8b90 100644 --- a/unittests/InstructionCountCI/Primary.json +++ b/unittests/InstructionCountCI/Primary.json @@ -5079,14 +5079,12 @@ ] }, "cmc": { - "ExpectedInstructionCount": 5, + "ExpectedInstructionCount": 3, "Optimal": "No", "Comment": "0xf5", "ExpectedArm64ASM": [ "ldr w20, [x28, #728]", - "ubfx w21, w20, #29, #1", - "eor x21, x21, #0x1", - "bfi w20, w21, #29, #1", + "eor w20, w20, #0x20000000", "str w20, [x28, #728]" ] },