Like Jit64, JitArm64 now keeps track of the location of a guest register
using three booleans: Whether it is in ppcState, whether it is in a host
register, and whether it is a known immediate. The RegType enum remains
only for the purpose of keeping track of what format FPRs are stored in
in host registers.
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.
Fusion is one of the built-in styles that Qt ships with, and that is
generally supported in all platforms and handles custom color palettes
properly.
The color palettes have been borrowed from the Dolphin Memory Engine
buddy application.
The new styles are:
- **Fusion Light**
- **Fusion Dark Gray**
- **Fusion Dark**
A demo of each style on Windows:
| System | Light | Dark | Fusion Light | Fusion Dark Gray | Fusion Dark |
| ------ | ----- | ---- | ------------ | ---------------- | ----------- |
| <img width="1920" height="1080" alt="Dolphin Emulator System style" src="https://github.com/user-attachments/assets/7f55a19d-d9a1-43d1-a435-1e1d5b29abe2" /> | <img width="1920" height="1080" alt="Dolphin Emulator Light style" src="https://github.com/user-attachments/assets/4c70f2f9-16b8-4777-b72b-55b2dffcd1e4" /> | <img width="1920" height="1080" alt="Dolphin Emulator Dark style" src="https://github.com/user-attachments/assets/5e669477-d2a5-4d19-b2c5-a2ed9bb1e6fe" /> | <img width="1920" height="1080" alt="Dolphin Emulator Light Fusion style" src="https://github.com/user-attachments/assets/b1f95c47-0691-4809-bd74-99e913c17684" /> | <img width="1920" height="1080" alt="Dolphin Emulator Dark Gray Fusion style" src="https://github.com/user-attachments/assets/c9d30aa3-f941-4fc5-806f-d3fbd2cae0cc" /> | <img width="1920" height="1080" alt="Dolphin Emulator Dark Fusion style" src="https://github.com/user-attachments/assets/123d2125-e126-4e8c-aa42-793ded8ffacc" /> |
> [!NOTE]
> Notice that the **Light** and **Dark** styles remain available only on
> Windows due to limitations on how styles in the various platforms
> handle (or mishandle) custom color palettes.
> [!IMPORTANT]
> Due to [`KDE-511547`](https://bugs.kde.org/show_bug.cgi?id=511547),
> after having used Breeze (default style in Plasma systems), top tool
> bars in tools areas will lose their correct background color; a
> restart will be required in order to get the updated color in the main
> window.
>
> UPDATE: The issue has been fixed upstream and should be available in
> KDE Plama 6.5.3 and newer.
The core no longer cares which thread is the host thread.
Cleaning up Android's HostThreadLock is left for another PR, in part
because the HostThreadLock in NativeConfig.cpp still serves a purpose,
and in part to make any issues easier to bisect.
By letting threads other than the host thread use things like
CPUThreadGuard, we can do a significant cleanup in AchievementsManager
in a later commit of this pull request.
Note: Some functions still can't be called from the CPU thread (or
threads the CPU thread might block on, like the GPU thread), but can
be called from any other thread.