Skip to content

Commit

Permalink
Add idle loop block tagging.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Jan 14, 2025
1 parent 8f73d94 commit 93c7fdd
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 11 deletions.
8 changes: 7 additions & 1 deletion GameConfig.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<GameConfigs>
<GameConfig Executable="SLUS_204.71;1" Title="Rygar - The Legendary Adventure">
<BlockFpRoundingMode Address="0x00147D88" Mode="NEAREST" />
<BlockFpRoundingMode Address="0x00147D88" Mode="NEAREST" Description="Fixes hang when entering first door." />
</GameConfig>
<GameConfig Executable="SLUS_210.48;1" Title="Evil Dead: Regeneration">
<IdleLoopBlock Address="0x00377898" />
</GameConfig>
<GameConfig Executable="SLUS_213.06;1" Title="Ghost Rider">
<IdleLoopBlock Address="0x002F43E8" />
</GameConfig>
</GameConfigs>
9 changes: 7 additions & 2 deletions Source/ee/EeBasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ void CEeBasicBlock::SetFpRoundingMode(Jitter::CJitter::ROUNDINGMODE fpRoundingMo
m_fpRoundingMode = fpRoundingMode;
}

void CEeBasicBlock::SetIsIdleLoopBlock()
{
m_isIdleLoopBlock = true;
}

void CEeBasicBlock::CompileProlog(CMipsJitter* jitter)
{
if(m_fpRoundingMode != DEFAULT_FP_ROUNDING_MODE)
Expand All @@ -22,7 +27,7 @@ void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
jitter->FP_SetRoundingMode(DEFAULT_FP_ROUNDING_MODE);
}

if(IsIdleLoopBlock())
if(m_isIdleLoopBlock || IsCodeIdleLoopBlock())
{
jitter->PushCst(MIPS_EXCEPTION_IDLE);
jitter->PullRel(offsetof(CMIPS, m_State.nHasException));
Expand All @@ -31,7 +36,7 @@ void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
CBasicBlock::CompileEpilog(jitter, loopsOnItself);
}

bool CEeBasicBlock::IsIdleLoopBlock() const
bool CEeBasicBlock::IsCodeIdleLoopBlock() const
{
enum OP
{
Expand Down
5 changes: 4 additions & 1 deletion Source/ee/EeBasicBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ class CEeBasicBlock : public CBasicBlock
using CBasicBlock::CBasicBlock;

void SetFpRoundingMode(Jitter::CJitter::ROUNDINGMODE);
void SetIsIdleLoopBlock();

protected:
void CompileProlog(CMipsJitter*) override;
void CompileEpilog(CMipsJitter*, bool) override;

private:
bool IsIdleLoopBlock() const;
bool IsCodeIdleLoopBlock() const;

static constexpr auto DEFAULT_FP_ROUNDING_MODE = Jitter::CJitter::ROUND_TRUNCATE;
Jitter::CJitter::ROUNDINGMODE m_fpRoundingMode = DEFAULT_FP_ROUNDING_MODE;

bool m_isIdleLoopBlock = false;
};
13 changes: 11 additions & 2 deletions Source/ee/EeExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ CEeExecutor::CEeExecutor(CMIPS& context, uint8* ram)
m_pageSize = framework_getpagesize();
}

void CEeExecutor::SetBlockFpRoundingModes(BlockFpRoundingModes blockFpRoundingMode)
void CEeExecutor::SetBlockFpRoundingModes(BlockFpRoundingModeMap blockFpRoundingModes)
{
m_blockFpRoundingModes = std::move(blockFpRoundingMode);
m_blockFpRoundingModes = std::move(blockFpRoundingModes);
}

void CEeExecutor::SetIdleLoopBlocks(IdleLoopBlockSet idleLoopBlocks)
{
m_idleLoopBlocks = std::move(idleLoopBlocks);
}

void CEeExecutor::AddExceptionHandler()
Expand Down Expand Up @@ -182,6 +187,10 @@ BasicBlockPtr CEeExecutor::BlockFactory(CMIPS& context, uint32 start, uint32 end
{
result->SetFpRoundingMode(blockFpRoundingModeIterator->second);
}
if(m_idleLoopBlocks.count(start))
{
result->SetIsIdleLoopBlock();
}

result->Compile();
if(!hasBreakpoint)
Expand Down
9 changes: 6 additions & 3 deletions Source/ee/EeExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
class CEeExecutor : public CGenericMipsExecutor<BlockLookupTwoWay>
{
public:
using BlockFpRoundingModes = std::map<uint32, Jitter::CJitter::ROUNDINGMODE>;
using IdleLoopBlockSet = std::set<uint32>;
using BlockFpRoundingModeMap = std::map<uint32, Jitter::CJitter::ROUNDINGMODE>;

CEeExecutor(CMIPS&, uint8*);
virtual ~CEeExecutor() = default;

void SetBlockFpRoundingModes(BlockFpRoundingModes);
void SetBlockFpRoundingModes(BlockFpRoundingModeMap);
void SetIdleLoopBlocks(IdleLoopBlockSet);

void AddExceptionHandler();
void RemoveExceptionHandler();
Expand All @@ -37,7 +39,8 @@ class CEeExecutor : public CGenericMipsExecutor<BlockLookupTwoWay>
typedef std::map<CachedBlockKey, BasicBlockPtr> CachedBlockMap;
CachedBlockMap m_cachedBlocks;

BlockFpRoundingModes m_blockFpRoundingModes;
IdleLoopBlockSet m_idleLoopBlocks;
BlockFpRoundingModeMap m_blockFpRoundingModes;

uint8* m_ram = nullptr;
size_t m_pageSize = 0;
Expand Down
22 changes: 20 additions & 2 deletions Source/ee/PS2OS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,8 @@ void CPS2OS::ApplyGameConfig()
return;
}

CEeExecutor::BlockFpRoundingModes blockFpRoundingModes;
CEeExecutor::BlockFpRoundingModeMap blockFpRoundingModes;
CEeExecutor::IdleLoopBlockSet idleLoopBlocks;

for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigsNode, "GameConfig");
!itNode.IsEnd(); itNode++)
Expand Down Expand Up @@ -702,7 +703,24 @@ void CPS2OS::ApplyGameConfig()
blockFpRoundingModes.insert(std::make_pair(address, roundingMode));
}

static_cast<CEeExecutor*>(m_ee.m_executor.get())->SetBlockFpRoundingModes(std::move(blockFpRoundingModes));
for(Framework::Xml::CFilteringNodeIterator itNode(gameConfigNode, "IdleLoopBlock");
!itNode.IsEnd(); itNode++)
{
auto node = (*itNode);

const char* addressString = node->GetAttribute("Address");
if(!addressString) continue;

uint32 address = 0;
if(sscanf(addressString, "%x", &address) == 0) continue;

idleLoopBlocks.insert(address);
}

auto executor = static_cast<CEeExecutor*>(m_ee.m_executor.get());
executor->SetBlockFpRoundingModes(std::move(blockFpRoundingModes));
executor->SetIdleLoopBlocks(std::move(idleLoopBlocks));

break;
}
}
Expand Down

0 comments on commit 93c7fdd

Please sign in to comment.