Every load hashed all known functions again, for the replacement hooks:
2.4-6 ms, about half the load. Functions in module code the load left as
it was keep their hash, so only the rest is hashed now (0.5-1 ms). The
code is compared on every load for this, not only with a JIT.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A module the game loaded before the state was saved, but that this run never loaded, was never
scanned, so loading such a state left all of its code without function replacements and hooks
(and without functions in the debugger). Scan any loaded module with no analyzed functions in its
text range before rehashing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The function list is from before the load, where other code (an overlay
module) may have been. Hashing it again from the loaded memory keeps the
hooks to code that actually matches.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
WriteMMIO_U32 was missing the return after the kernel-mode check, so a
user-mode write raised the exception and then went through anyway. The
other five MMIO accessors already return here; this one lost it when the
GPIO/syscon branches were added.
Int_Vrot scanned all four entries of dregs, but GetVectorRegs only fills
the first n - so a vrot with vs == 0 (S000) matched a lane that isn't
there and took the cosine from it. The IR backend gets this right via
IsOverlapSafe, so the two disagreed.
The breakpoint checks in MIPSInterpret and RunUntilDowncountZeroWithChecks
read instr->flags without checking for null, which MIPSGetInstruction
returns for the eight primary opcodes (and many subops) that don't decode.
With a memcheck or register breakpoint active, landing on one of those
crashed instead of raising ILLEGAL.
Also: GetVectorOverlap decoded the second vector with size1 (no callers
today), and RegisterFunction left most of its AnalyzedFunction
uninitialized, including the size that ends up in knownfuncs.ini.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
These generally work, but likely delay slots will make downcount slightly
off, and won't resume when you hit run again without manually stepping
through them.
So things like Star Ocean work, and game memcpy()'s to GPU work.
This will make game start on mobile a bit slower, though. And there could
still be bugs so leaving as an option, but seems pretty stable. Didn't
realize it wasn't enabled by default.
Also auto-saves hashmap additions and reapplies the hashmap on function
rename so that if you rename a function that exists in several copies
they will all be labelled.
Note that actual function replacement is not activated yet.