Like the previous commit did for Jit64, JitArm64 can now handle the
combination of a value simultaneously being in a host register and being
a known immediate.
Unlike with Jit64, I've put the codegen-affecting changes in this commit
and the move away from the RegType enum in a follow-up commit. This is
in part because the design of JitArm64 made it easy to implement the
codegen-affecting changes without combining it with a big bang
refactorization, and in part because we need to keep RegType around for
keeping track of different float formats in Arm64FPRCache, complicating
the refactorization a bit.
They're now stored in ConstantPropagation instead.
I've also removed the LocationType enum. The location of each guest
register is now tracked using three booleans: Whether it is in ppcState,
whether it is in a host register, and whether it is a known immediate.
The first two of these booleans are stored in the register cache, and
the last one is stored in ConstantPropagation. This new model allows us
to handle the combination of a value simultaneously being in a host
register and being a known immediate. It also keeps track of which
registers are dirty, which was previously kept track of in X64CachedReg.
The old model maps to the new model as follows:
default host_reg immediate
Default true false false
Discarded false false false
Bound (!dirty) true false
Immediate false false true
SpeculativeImmediate true false true
[previously unrepresentable] (!dirty) true true
This commit makes the JIT set/clear the individual registers of
ConstantPropagation immediately instead of at the end of the
instruction. This is needed to prevent Jit64::ComputeRC, which reads
from a register written to earlier during the same instruction, from
reading back stale register values from ConstantPropagation in the next
commit.
To find out whether a host register needs to be unlocked, FlushRegisters
checks if the guest register is known to be a zero immediate. This works
right now, but it will stop working correctly once we gain the ability
to have a guest register be a known immediate and be in a host register
at the same time, because a register that's known to be a zero immediate
may have had a host register allocated prior to the call to
FlushRegisters. Instead, we should check whether the register is
RegType::Register after we're done calling BindForRead.
Restructuring things in this way brings two immediate benefits:
* Code is deduplicated between Jit64 and JitArm64.
* Materializing an immediate value in a register no longer results in us
forgetting what the immediate value was.
As a more long-term benefit, this lets us also run constant propagation
as part of PPCAnalyst, which could let us do cool stuff in the future
like statically determining whether a conditional branch will be taken.
But I have nothing concrete planned for that right now.
Creates a layer outside the game config layer system and passes it to the created gfx widows, so as to not interfere with the global config system.
Supports multiple game properties being open at once.
Supports editing while a game is playing, but the options only save and update the active game when the window is closed.
Right-clicking will remove a property from the game ini.