ME: Skip the rest of a slice the ME spends polling for the main CPU

Most homebrew ME code waits in a loop like lw t0, flag; beq t0, zero,
loop; nop: Daedalus/MElib/NooDS's mediaengine.prx, snes9xTYL, PMP Mod,
Yabause, FBA, the Touhou ports (with a few nops in it). Such a loop stores
nothing, has only plain loads, integer ALU ops, nops and branches, and
writes every register it reads before reading it in a pass, so every
pass goes the same way while memory stays the same - which it does while
the ME runs, since the main CPU doesn't. At the top of one, between
parts of a slice, the ME interprets a pass, and if it comes back to the
top, waits out the rest of the slice.

Loops that also store (a heartbeat counter) or span several blocks
aren't recognized, nor are delay loops counting down a register.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-21 11:07:37 +02:00
1 parent 2543a3e52b
commit caed1bc5f2
5 files changed
+208 -1

No files matched your search

+1
View File
@@ -3738,6 +3738,7 @@ TestItem availableTests[] = {
TEST_ITEM(MESpace),
TEST_ITEM(MeCore),
TEST_ITEM(MeInterrupts),
TEST_ITEM(MeWait),
TEST_ITEM(CPUEquivalence),
TEST_ITEM(CPURoundingMode),
TEST_ITEM(VFPUDotJit),