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

Method LODSOp

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

Source from the content-addressed store, hash-verified

3403}
3404
3405void OpDispatchBuilder::LODSOp(OpcodeArgs) {
3406 if (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) {
3407 LogMan::Msg::EFmt("Can't handle adddress size");
3408 DecodeFailure = true;
3409 return;
3410 }
3411
3412 const auto Size = OpSizeFromSrc(Op);
3413 const bool Repeat = (Op->Flags & (FEXCore::X86Tables::DecodeFlags::FLAG_REP_PREFIX | FEXCore::X86Tables::DecodeFlags::FLAG_REPNE_PREFIX)) != 0;
3414
3415 if (!Repeat) {
3416 Ref Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags, X86Tables::DecodeFlags::FLAG_DS_PREFIX);
3417
3418 auto Src = _LoadMemAutoTSO(GPRClass, Size, Dest_RSI, Size);
3419
3420 StoreResult(GPRClass, Op, Src, OpSize::iInvalid);
3421
3422 // Offset the pointer
3423 Ref TailDest_RSI = LoadGPRRegister(X86State::REG_RSI);
3424 StoreGPRRegister(X86State::REG_RSI, OffsetByDir(TailDest_RSI, IR::OpSizeToSize(Size)));
3425 } else {
3426 // Calculate flags early. because end of block
3427 CalculateDeferredFlags();
3428
3429 ForeachDirection([this, Op, Size](int32_t PtrDir) {
3430 // XXX: Theoretically LODS could be optimized to
3431 // RSI += {-}(RCX * Size)
3432 // RAX = [RSI - Size]
3433 // But this might violate the case of an application scanning pages for read permission and catching the fault
3434 // May or may not matter
3435
3436 auto JumpStart = Jump();
3437 // Make sure to start a new block after ending this one
3438 auto LoopStart = CreateNewCodeBlockAfter(GetCurrentBlock());
3439 SetJumpTarget(JumpStart, LoopStart);
3440 SetCurrentCodeBlock(LoopStart);
3441 StartNewBlock();
3442
3443 Ref Counter = LoadGPRRegister(X86State::REG_RCX);
3444
3445 // Can we end the block?
3446
3447 // We leave if RCX = 0
3448 auto CondJump_ = CondJump(Counter, {COND_EQ});
3449
3450 auto LoopTail = CreateNewCodeBlockAfter(LoopStart);
3451 SetFalseJumpTarget(CondJump_, LoopTail);
3452 SetCurrentCodeBlock(LoopTail);
3453 StartNewBlock();
3454
3455 // Working loop
3456 {
3457 Ref Dest_RSI = MakeSegmentAddress(X86State::REG_RSI, Op->Flags, X86Tables::DecodeFlags::FLAG_DS_PREFIX);
3458
3459 auto Src = _LoadMemAutoTSO(GPRClass, Size, Dest_RSI, Size);
3460
3461 StoreResult(GPRClass, Op, Src, OpSize::iInvalid);
3462

Callers

nothing calls this directly

Calls 2

EFmtFunction · 0.85
OpSizeToSizeFunction · 0.85

Tested by

no test coverage detected