MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / CMOVOp

Method CMOVOp

FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp:657–688  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

655}
656
657void OpDispatchBuilder::CMOVOp(OpcodeArgs) {
658 const auto GPRSize = GetGPROpSize();
659 const auto OP = Op->OP & 0xF;
660 const auto ResultSize = std::max(OpSize::i32Bit, OpSizeFromSrc(Op));
661
662 CalculateDeferredFlags();
663
664 // Destination is always a GPR.
665 Ref Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GPRSize, Op->Flags);
666 Ref Src {}, SrcCond {};
667 if (Op->Src[0].IsGPR()) {
668 Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], GPRSize, Op->Flags);
669 } else {
670 Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
671 }
672
673 if (auto Cond = DecodeNZCVCondition(OP); Cond) {
674 // Use raw select since DecodeNZCVCondition handles the carry invert
675 SrcCond = _NZCVSelect(ResultSize, *Cond, Src, Dest);
676 } else {
677 // Raw value contains inverted PF in bottom bit
678 Ref Cmp = LoadPFRaw(false, ParityJumpIsJP(OP));
679 SaveNZCV();
680
681 // Because we're only clobbering NZCV internally, we ignore all carry flag
682 // shenanigans and just use the raw test and raw select.
683 _TestNZ(OpSize::i32Bit, Cmp, _InlineConstant(1));
684 SrcCond = _NZCVSelect(ResultSize, {COND_NEQ}, Src, Dest);
685 }
686
687 StoreResult(GPRClass, Op, SrcCond, OpSize::iInvalid);
688}
689
690void OpDispatchBuilder::CondJUMPOp(OpcodeArgs) {
691 // Calculate flags early.

Callers

nothing calls this directly

Calls 2

ParityJumpIsJPFunction · 0.85
IsGPRMethod · 0.45

Tested by

no test coverage detected