From 0123946ed151ce2c5e60c0ed8da3eca659085c6d Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 30 Nov 2024 23:46:04 -0800 Subject: [PATCH 1/2] FEXCore: Removes GetGPRSize and convert all uses to GetGPROpSize Only a few remaining uses left, easy enough to convert. This finally switches the final few uses over. NFC --- FEXCore/Source/Interface/Context/Context.h | 5 ----- FEXCore/Source/Interface/Core/Core.cpp | 14 +++++--------- FEXCore/Source/Interface/Core/Frontend.cpp | 8 ++++---- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 6 +++--- FEXCore/Source/Interface/Core/OpcodeDispatcher.h | 6 +++--- .../Interface/Core/OpcodeDispatcher/Vector.cpp | 4 ++-- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/FEXCore/Source/Interface/Context/Context.h b/FEXCore/Source/Interface/Context/Context.h index b49805362f..ab5e6fd465 100644 --- a/FEXCore/Source/Interface/Context/Context.h +++ b/FEXCore/Source/Interface/Context/Context.h @@ -299,11 +299,6 @@ class ContextImpl final : public FEXCore::Context::Context { CompileCodeResult CompileCode(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestRIP, uint64_t MaxInst = 0); uintptr_t CompileBlock(FEXCore::Core::CpuStateFrame* Frame, uint64_t GuestRIP, uint64_t MaxInst = 0); - uint8_t GetGPRSize() const { - return Config.Is64BitMode ? 8 : 4; - } - - // TODO: Temporary while OpcodeDispatcher shifts over IR::OpSize GetGPROpSize() const { return Config.Is64BitMode ? IR::OpSize::i64Bit : IR::OpSize::i32Bit; } diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 1dbaa53a92..073130b3c2 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -562,7 +562,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue Thread->OpDispatcher->BeginFunction(GuestRIP, CodeBlocks, BlockInfo->TotalInstructionCount); - const uint8_t GPRSize = GetGPRSize(); + const auto GPRSize = GetGPROpSize(); for (size_t j = 0; j < CodeBlocks->size(); ++j) { const FEXCore::Frontend::Decoder::DecodedBlocks& Block = CodeBlocks->at(j); @@ -578,7 +578,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue if (InstsInBlock == 0) { // Special case for an empty instruction block. - Thread->OpDispatcher->ExitFunction(Thread->OpDispatcher->_EntrypointOffset(IR::SizeToOpSize(GPRSize), Block.Entry - GuestRIP)); + Thread->OpDispatcher->ExitFunction(Thread->OpDispatcher->_EntrypointOffset(GPRSize, Block.Entry - GuestRIP)); } for (size_t i = 0; i < InstsInBlock; ++i) { @@ -621,8 +621,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue Thread->OpDispatcher->SetCurrentCodeBlock(CodeWasChangedBlock); Thread->OpDispatcher->_ThreadRemoveCodeEntry(); - Thread->OpDispatcher->ExitFunction( - Thread->OpDispatcher->_EntrypointOffset(IR::SizeToOpSize(GPRSize), Block.Entry + BlockInstructionsLength - GuestRIP)); + Thread->OpDispatcher->ExitFunction(Thread->OpDispatcher->_EntrypointOffset(GPRSize, Block.Entry + BlockInstructionsLength - GuestRIP)); auto NextOpBlock = Thread->OpDispatcher->CreateNewCodeBlockAfter(CurrentBlock); @@ -652,7 +651,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue } // Invalid instruction Thread->OpDispatcher->InvalidOp(DecodedInfo); - Thread->OpDispatcher->ExitFunction(Thread->OpDispatcher->_EntrypointOffset(IR::SizeToOpSize(GPRSize), Block.Entry - GuestRIP)); + Thread->OpDispatcher->ExitFunction(Thread->OpDispatcher->_EntrypointOffset(GPRSize, Block.Entry - GuestRIP)); } const bool NeedsBlockEnd = @@ -666,11 +665,8 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue } if (NeedsBlockEnd) { - const uint8_t GPRSize = GetGPRSize(); - // We had some instructions. Early exit - Thread->OpDispatcher->ExitFunction( - Thread->OpDispatcher->_EntrypointOffset(IR::SizeToOpSize(GPRSize), Block.Entry + BlockInstructionsLength - GuestRIP)); + Thread->OpDispatcher->ExitFunction(Thread->OpDispatcher->_EntrypointOffset(GPRSize, Block.Entry + BlockInstructionsLength - GuestRIP)); break; } diff --git a/FEXCore/Source/Interface/Core/Frontend.cpp b/FEXCore/Source/Interface/Core/Frontend.cpp index b48227a671..b8d8af19c1 100644 --- a/FEXCore/Source/Interface/Core/Frontend.cpp +++ b/FEXCore/Source/Interface/Core/Frontend.cpp @@ -926,7 +926,7 @@ void Decoder::BranchTargetInMultiblockRange() { // If the RIP setting is conditional AND within our symbol range then it can be considered for multiblock uint64_t TargetRIP = 0; - const uint8_t GPRSize = CTX->GetGPRSize(); + const auto GPRSize = CTX->GetGPROpSize(); bool Conditional = true; switch (DecodeInst->OP) { @@ -954,7 +954,7 @@ void Decoder::BranchTargetInMultiblockRange() { default: return; break; } - if (GPRSize == 4) { + if (GPRSize == IR::OpSize::i32Bit) { // If we are running a 32bit guest then wrap around addresses that go above 32bit TargetRIP &= 0xFFFFFFFFU; } @@ -995,13 +995,13 @@ bool Decoder::BranchTargetCanContinue(bool FinalInstruction) const { } uint64_t TargetRIP = 0; - const uint8_t GPRSize = CTX->GetGPRSize(); + const auto GPRSize = CTX->GetGPROpSize(); if (DecodeInst->OP == 0xE8) { // Call - immediate target const uint64_t NextRIP = DecodeInst->PC + DecodeInst->InstSize; TargetRIP = DecodeInst->PC + DecodeInst->InstSize + DecodeInst->Src[0].Literal(); - if (GPRSize == 4) { + if (GPRSize == IR::OpSize::i32Bit) { // If we are running a 32bit guest then wrap around addresses that go above 32bit TargetRIP &= 0xFFFFFFFFU; } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 5e2ce10047..6020dcd41c 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -1820,10 +1820,10 @@ void OpDispatchBuilder::BZHI(OpcodeArgs) { } void OpDispatchBuilder::RORX(OpcodeArgs) { - const auto SrcSize = GetSrcSize(Op); - const auto SrcSizeBits = SrcSize * 8; + const auto SrcSize = OpSizeFromSrc(Op); + const auto SrcSizeBits = IR::OpSizeAsBits(SrcSize); const auto Amount = Op->Src[1].Literal() & (SrcSizeBits - 1); - const auto GPRSize = CTX->GetGPRSize(); + const auto GPRSize = CTX->GetGPROpSize(); const auto DoRotation = Amount != 0 && Amount < SrcSizeBits; const auto IsSameGPR = Op->Src[0].IsGPR() && Op->Dest.IsGPR() && Op->Src[0].Data.GPR.GPR == Op->Dest.Data.GPR.GPR; diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 82b512c94b..e3045c5003 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -185,10 +185,10 @@ class OpDispatchBuilder final : public IREmitter { auto it = JumpTargets.find(NextRIP); if (it == JumpTargets.end()) { - const uint8_t GPRSize = CTX->GetGPRSize(); + const auto GPRSize = CTX->GetGPROpSize(); // If we don't have a jump target to a new block then we have to leave // Set the RIP to the next instruction and leave - auto RelocatedNextRIP = _EntrypointOffset(IR::SizeToOpSize(GPRSize), NextRIP - Entry); + auto RelocatedNextRIP = _EntrypointOffset(GPRSize, NextRIP - Entry); ExitFunction(RelocatedNextRIP); } else if (it != JumpTargets.end()) { Jump(it->second.BlockEntry); @@ -2056,7 +2056,7 @@ class OpDispatchBuilder final : public IREmitter { auto Shift = FEXCore::ilog2(Size); if (Shift) { - return _Lshl(IR::SizeToOpSize(CTX->GetGPRSize()), Dir, _Constant(Shift)); + return _Lshl(CTX->GetGPROpSize(), Dir, _Constant(Shift)); } else { return Dir; } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 3d5e55ffe6..b0a2ea53fc 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -2485,7 +2485,7 @@ Ref OpDispatchBuilder::XSaveBase(X86Tables::DecodedOp Op) { void OpDispatchBuilder::XSaveOpImpl(OpcodeArgs) { // NOTE: Mask should be EAX and EDX concatenated, but we only need to test // for features that are in the lower 32 bits, so EAX only is sufficient. - const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize()); + const auto OpSize = CTX->GetGPROpSize(); const auto StoreIfFlagSet = [this, OpSize](uint32_t BitIndex, auto fn, uint32_t FieldSize = 1) { Ref Mask = LoadGPRRegister(X86State::REG_RAX); @@ -2658,7 +2658,7 @@ void OpDispatchBuilder::FXRStoreOp(OpcodeArgs) { } void OpDispatchBuilder::XRstorOpImpl(OpcodeArgs) { - const auto OpSize = IR::SizeToOpSize(CTX->GetGPRSize()); + const auto OpSize = CTX->GetGPROpSize(); // If a bit in our XSTATE_BV is set, then we restore from that region of the XSAVE area, // otherwise, if not set, then we need to set the relevant data the bit corresponds to From ce9a860335a47ea7054fe36253556bed49ca164a Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 30 Nov 2024 23:56:46 -0800 Subject: [PATCH 2/2] OpcodeDispatcher: Also remove unused CacheIndexToSize --- FEXCore/Source/Interface/Core/OpcodeDispatcher.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index e3045c5003..ec6589c9c7 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -1857,17 +1857,6 @@ class OpDispatchBuilder final : public IREmitter { } } - unsigned CacheIndexToSize(int Index) { - // MMX registers are rounded up to 128-bit since they are shared with 80-bit - // x87 registers, even though MMX is logically only 64-bit. - if (Index >= AVXHigh0Index || ((Index >= MM0Index && Index <= MM7Index))) { - return 16; - } else { - return 1; - } - } - - // TODO: Temporary while OpcodeDispatcher shifts over IR::OpSize CacheIndexToOpSize(int Index) { // MMX registers are rounded up to 128-bit since they are shared with 80-bit // x87 registers, even though MMX is logically only 64-bit.