This fixes ROM swapping for x86/64, arm32 and arm64. On top of that it
improves speed by removing unnecessary slow paths on small ROMs for
arm32 and mips. If the ROM can fit in RAM, it will emit more efficient
code that assumes the ROM is fully loaded.
For low-memory Linux platforms it would be better to use some mmap'ed
ROM, that way the OS would transparently handle page swapping, which is
perhaps faster. Will investigate and follow up on this in a separate
commit.
gpsp doesn't differentiate between USER and SYSTEM mode, most likely
cause it is not that important for most games. This implements the modes
correctly and adds checks for privileged operations. Still some
bugs/hacks but it mostly fixes CPSR/SPSR reads/writes.
To implement PSR writes we are using a more refined masks and force mode
bit num. 4 to always be one. Reserved bits are forced to zero (this
needs to be validated on a real device).
This removes one branch and emits the region selection code directly in
the JIT cache. Trading memory for speed (although it's not a big
improvement).
This is a step towards enabling MMAP caches in ARM (due to the 32MB
offset limitation in branches).
This fixes a race condition that happens whenever the ROM cache is flushed but
the RAM one is not, causing any SWI calls (implemented as direct branches) to
jump to random instructions.
The fix could be to flush both caches at the same time (~expensive on
low mem platforms), use indirect jumps (a bit expensive) or emit the SWI
handler below the watermark to ensure it is never flushed. This is cheap
and effective, requires minimal changes.
Removed the last bits of text relocations by moving all relevant RAMs to
the stub reachable area. This should be as fast or even faster than
previous code.
Cleans up a ton of whitespace in cpu.c (like 100KB!) and improves
readability of some massive decode statements.
Added an optimization for PC-relative loads (pool load) in ROM (since
it's read only and cannot possibily change) that directly emits an
immediate load. This is way faster, specially in MIPS/x86, ARM can be
even faster if we rewrite the immediate load macros to also use a pool.
Using an invalid SP makes Vita crash (for an unkown reason) and makes
things like C signal handlers crash (luckily Retroarch doesn't use
them). It is also a violation of the ABI and not a great idea.
Recycled some little used registers to free SP. Perf should be roughly
the same.
I think this does not make a difference at all in the code, since PC is
treated in a special way anyway (reloaded with an immediate when read
and treated as an indirect branch when written). However for the sake of
completeness I'm undoing what I did. (The comma fix stays :P)
Turns out there were a couple of very interesting and hard to track
bugs. A missing comma made the reg list too short, leaving the 31th
element at the mercy of the linker ordering algorithm, which seems to
work in some cases depending on the compiler version.
Also the cache flush code seemed not to work on my machine (OGA),
not sure why it wored in the past :/