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

Method CMPSOp

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

Source from the content-addressed store, hash-verified

3283}
3284
3285void OpDispatchBuilder::CMPSOp(OpcodeArgs) {
3286 if (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) {
3287 LogMan::Msg::EFmt("Can't handle adddress size");
3288 DecodeFailure = true;
3289 return;
3290 }
3291
3292 const auto Size = OpSizeFromSrc(Op);
3293
3294 bool Repeat = Op->Flags & (FEXCore::X86Tables::DecodeFlags::FLAG_REPNE_PREFIX | FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX);
3295 if (!Repeat) {
3296 // Default DS prefix
3297 Ref Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags, X86Tables::DecodeFlags::FLAG_DS_PREFIX);
3298 // Only ES prefix
3299 Ref Dest_RDI = MakeSegmentAddress(X86State::REG_RDI, 0, X86Tables::DecodeFlags::FLAG_ES_PREFIX, true);
3300
3301 auto Src1 = _LoadMemAutoTSO(GPRClass, Size, Dest_RDI, Size);
3302 auto Src2 = _LoadMemAutoTSO(GPRClass, Size, Dest_RSI, Size);
3303
3304 CalculateFlags_SUB(OpSizeFromSrc(Op), Src2, Src1);
3305
3306 auto PtrDir = LoadDir(IR::OpSizeToSize(Size));
3307
3308 // Offset the pointer
3309 Dest_RDI = Add(OpSize::i64Bit, Dest_RDI, PtrDir);
3310 StoreGPRRegister(X86State::REG_RDI, Dest_RDI);
3311
3312 // Offset second pointer
3313 Dest_RSI = Add(OpSize::i64Bit, Dest_RSI, PtrDir);
3314 StoreGPRRegister(X86State::REG_RSI, Dest_RSI);
3315 } else {
3316 // Calculate flags early.
3317 CalculateDeferredFlags();
3318
3319 bool REPE = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX;
3320
3321 // If rcx = 0, skip the whole loop.
3322 Ref Counter = LoadGPRRegister(X86State::REG_RCX);
3323 auto OuterJump = CondJump(Counter, {COND_EQ});
3324
3325 auto BeforeLoop = CreateNewCodeBlockAfter(GetCurrentBlock());
3326 SetFalseJumpTarget(OuterJump, BeforeLoop);
3327 SetCurrentCodeBlock(BeforeLoop);
3328 StartNewBlock();
3329
3330 ForeachDirection([this, Op, Size, REPE](int32_t PtrDir) {
3331 IRPair<IROp_CondJump> InnerJump;
3332 auto JumpIntoLoop = Jump();
3333
3334 // Setup for the loop
3335 auto LoopHeader = CreateNewCodeBlockAfter(GetCurrentBlock());
3336 SetCurrentCodeBlock(LoopHeader);
3337 StartNewBlock();
3338 SetJumpTarget(JumpIntoLoop, LoopHeader);
3339
3340 // Working loop
3341 {
3342 // Default DS prefix

Callers

nothing calls this directly

Calls 2

EFmtFunction · 0.85
OpSizeToSizeFunction · 0.85

Tested by

no test coverage detected