When we try to JIT from a block which doesn't exist, don't JIT any code;
just update the PPC state to indicate an ISI. This is a little simpler,
and avoids abusing the JIT block cache.
JitIL's fastmem was stubbed out when Sonicadvance1 merged JitARMIL
into the tree. Since JitARMIL has been deleted, I simply re-arrange
the inheritance to base JitIL on Jitx86Base, so it can inherit the
backpatch function.
Povray Benchmark: 1985 seconds to 1316 seconds.
Has been broken since the flags-opt merge. The idle skipping code in
JitIL was very brittle and depended on the IL of it's inputs not
changing in any way.
flags-opt changed the IR generated by the cmp instruction, which is part
of the idle loop, causing JitIL to break in really weird ways, which
were almost impossible to track down.
This fixes various wii games crashing/not booting and the Regspill
error on (all?) gamecube mmu games.
Uses are split into three categories:
- Arbitrary (except for size savings) - constants like RSCRATCH are
used.
- ABI (i.e. RAX as return value) - ABI_RETURN is used.
- Fixed by architecture (RCX shifts, RDX/RAX for some instructions) -
explicit register is kept.
In theory this allows the assignments to be modified easily. I verified
that I was able to run Melee with all the registers changed, although
there may be issues if RSCRATCH[2] and ABI_PARAM{1,2} conflict.
Rather than using a variety of registers including RSI, ABI_PARAM1
(either RCX or RDI), RCX, and RDX, the rule is:
- RDI and RSI are never used. This allows them to be allocated on Unix,
bringing parity with Windows.
- RDX is a permanent temporary register along with RAX (and is thus not
FlushLocked). It's used frequently enough that allocating it would
probably be a bad idea, as it would constantly get flushed.
- RCX is allocatable, but is flushed in two situations:
- Non-immediate shifts (rlwnm), because x86 requires RCX to be used.
- Paired single loads and stores, because they require three
temporary registers: the helper functions take two integer
arguments, and another register is used as an index to get the
function address.
These should be relatively rare.
While we're at it, in stores, use the registers directly where possible
rather than always using temporaries (by making SafeWriteRegToReg
clobber less). The address doesn't need to be clobbered in the usual
case, and on CPUs with MOVBE, neither does the value.
Oh, and get rid of a useless MEMCHECK.
This commit does not actually add new registers to the allocation order;
it is intended to test for any performance or correctness issues
separately.
The existing implementations produce answers which aren't consistent with
the hardware, and games care about correct floating point math.
These can be reimplemented at some point in the future, if someone cares
enough, but the general case is probably too much code to inline.
(I'm leaving the ARM implementations in place by request, even though they
suffer the same issues.)
Having a bunch of nearly identical code sitting around isn't a good idea,
so fix that. JITIL had a couple of extra entry points into the JIT main
loop, so adjust the code appropriately.
Also fixes Issue 7186.
They are semantically equivalent and according to Agner Fog they can run
on more execution ports than their floating point counterparts (at least
on Intel CPUs).
Our defines were never clear between what meant 64bit or x86_64
This makes a clear cut between bitness and architecture.
This commit also has the side effect of bringing up aarch64 compiling support.
- remove unused variables
- reduce the scope where it makes sense
- correct limits (did you know that strcat()'s last parameter does not
include the \0 that is always added?)
- set some free()'d pointers to NULL