fcmpo and fcmpu can be matched by the REORDER_CMP pass, as they set CR0
and they can cause interrupts if the fpu is disabled.
So we add an extra check to make sure op a is an integer op too.
This is unused, and since it had the same value as FL_OUT_D, it was unnecessarily setting the rS register as an output, even on instructions that only have FL_OUT_D set.
The PowerPC CPU has bits in MSR (DR and IR) which control whether
addresses are translated. We should respect these instead of mixing
physical addresses and translated addresses into the same address space.
This is mostly mass-renaming calls to memory accesses APIs from places
which expect address translation to use a different version from those
which do not expect address translation.
This does very little on its own, but it's the first step to a correct BAT
implementation.
Now it should be easier to merge more than 2-instruction-long sequences.
Also correct some minor inconsistencies in behavior between instruction
merging cases.
Optimistically assume used GQRs are 0 in blocks that only use one GQR, and
bail at the start of the block and recompile if that assumption fails.
Many games use almost entirely unquantized stores (e.g. Rebel Strike, Sonic
Colors), so this will likely be a big performance improvement across the board
for games with heavy use of paired singles.
In rare cases, this can result in a violation of the JIT block cache constraint
that blocks must end in the same place. This can cause instability, lockups,
due to blocks not properly being invalidated properly.
l Please enter the commit message for your changes. Lines starting
Small TLB lookup optimizations: this is the hot path for MMU code, so try to
make it better.
Template the TLB lookup functions based on the lookup type (opcode, data,
no exception).
Clean up the Read/Write functions and make them more consistent.
Add an early-exit path for MMU accesses to ReadFromHardware/WriteToHardware.
dcbz: just don't use GetPointer, that can't be right anyways
ppcanalyst: don't print "instruction hex 0" messages in MMU mode, where ISIs
are expected.
lmw/stmw weren't properly setting input and output registers since they use multiple registers.
dcbz was just missing a flag in the instruction tables.
If the inputs are both float singles, and the top half is known to be identical
to the bottom half, we can use packed arithmetic instead of scalar to skip
the movddup.
This is slower on a few rather old CPUs, plus the Atom+Silvermont, so detect
Atom and disable it in that case.
Also avoid PPC_FP on stores if we know that the output came from a float op.
This is a higher level, more concise wrapper for bitsets which supports
efficiently counting and iterating over set bits. It's similar to
std::bitset, but the latter does not support efficient iteration (and at
least in libc++, the count algorithm is subpar, not that it really
matters). The converted uses include both bitsets and, notably,
considerably less efficient regular arrays (for in/out registers in
PPCAnalyst).
Unfortunately, this may slightly pessimize unoptimized builds.
Should be at least a bit better than the previous LRU approach. Currently
has two basic components: whether a register is dirty (dirty registers need
to be stored, so clobbering them hurts more) and how many other registers will
be used between now and the next time a register gets used.
Also don't pre-load values that don't need to be in registers.
This should dramatically reduce code size in the case of blocks with
lots of branches, and certainly doesn't hurt elsewhere either.
This can probably be improved a good bit through smarter tracking of register
usage, e.g. discarding registers that are going to be overwritten, but this
is a good start and should help reduce code size and register pressure.
Unlike that sort of change, this is a "safe" patch; it only flushes registers,
which can't affect correctness, unlike actually discarding data.
As part of this, refactor PPCAnalyst to support distinguishing between
float and integer registers (to properly handle instructions that access
both, like floating-point loads and stores).
Also update every instruction in the interpreter flags table I could find
that didn't have all the correct flags.
Tries as hard as possible to push carry-using operations (like addc and adde)
next to each other. Refactor the instruction reordering to be more flexible
and allow multiple passes.
353 -> 192 x86 instructions on a carry-heavy code block in Pokemon Puzzle.
12% faster overall in Pokemon Puzzle; probably less in typical games (Virtual
Console games seem to be carry-heavy for some reason; maybe a different
compiler?)
In situations where conditional continue isn't supported + if a JIT doesn't implement a instruction that has the FL_ENDBLOCK flag. This would cause an
infinite loop.
In reality all the JITs should implement every FL_ENDBLOCK instruction regardless, but JITIL doesn't implement tw/twi which are FL_ENDBLOCK
instructions.
Doesn't support all the FPSCR flags, just the FPRF ones.
Add PPCAnalyzer support to remove unnecessary FPRF calculations.
POV-ray benchmark with enableFPRF forced on for an extreme comparison:
Before: 1500s
After, fmul/fmadd only: 728s
After, all float: 753s
In real games that use FPRF, like F-Zero GX, FPRF previously cost a few percent
of total runtime.
Since FPRF is so much faster now, if enableFPRF is set, just do it for every
float instruction, not just fmul/fmadd like before. I don't know if this will
fix any games, but there's little good reason not to.