Commit Graph
28 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 6e475258da ME: Run the Media Engine on the ARM64 and x64 JITs
The native dispatcher generated for the ME leaves when its downcount
runs out instead of calling CoreTiming::Advance, and IRNativeJit gets
RunDowncount. Pointerify is decided from the CPU's own memory base. ARM32,
RISC-V and LoongArch64 still give the ME the IR interpreter.

LoadKernel/StoreKernel are now compiled on ARM64 and x64 rather than
going through the IR interpreter one op at a time: memory directly, or a
call to fixed code (which saves the caller-saved registers guest values
live in) for 0xBC000000-0xBFFFFFFF. ARM64's block size estimate counts
them as such. The 16-bit ones stay generic while the software renderer's
depth mirrors are active, as Load16/Store16 do. That matters for the main
CPU's kernel code too, and for all code while the ME is emulated, which
runs in kernel mode everywhere. mcidclan's me-soft-interrupt went from
476 billion to 6.4 billion host instructions for 3 emulated seconds,
ending with the same ME counter as the IR interpreter.

The ME unit tests run on the native JIT too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 10:28:50 +02:00
Henrik RydgårdandClaude Opus 5.5 39e6e7b29b IR JITs: Split the IR interpreter out, and keep IR to it
IRJit is now the base the IR JITs share: the frontend, the table of guest
blocks, and compiling and invalidating them. IRInterpreterJit and
IRNativeJit are the two kinds. Only IRInterpreterJit keeps IR, in its arena,
along with its dispatch loop and per-block profile.

The native JITs no longer keep the IR they compiled from. The debugger and
the --jit-profile report compile a native block's IR again when they want it,
on a copy of the frontend's state, which gives what ran unless the code or
that state has changed since.

IRBlockCache and IRBlock become JitBlockTable and JitBlock: where each block
came from, the page lookup for invalidation, and the block shadow entry (an
arena or native code offset, depending on the JIT). One IRJitDebugInterface
serves both JITs, taking the MIPS code from the table and the IR and host code
from the JIT, in place of the native JIT's own debug interface.

The native backends don't see the table at all. They compile a span of IR for
a block number and start PC, and keep what they need about their own blocks
(start PC, code offset, which block starts where, for linking) next to the
exits they already tracked. The register cache takes the instructions
directly.

The tracer's block index now goes into the IR before the block is stored, so
native blocks get it too. The unused FindByCookie goes. TestJit checks that
the native JIT keeps no IR, and can still show it. The JIT stats overlay no
longer shows IR for the native JITs. MIPSState can't be copied, now that it
owns its JIT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 12:09:16 +02:00
Henrik RydgårdandClaude Opus 5.5 5a9cbf007c CPU: Pass the MIPSState explicitly where it was already at hand
The JIT backends' calls out of generated code (the MIPS and IR interpreter
fallbacks, and the bad address report) now take the state the backend was
built for instead of reading currentMIPS. Likewise the interpreter's tick
check, the IR dispatcher's Advance, and a couple of debugger helpers.

MIPSState::InitRegisters() no longer sets currentMIPS; the boot paths set it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 09:47:48 +02:00
Henrik RydgårdandClaude Opus 5.5 b175bc859a IR JIT: Grow the native code space to 24 MB
Big games fill 16 MB in normal play. It's now one constant shared by
every backend. ARM32's 32 MB branch range is the limit on going higher
there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-17 15:11:47 +02:00
Henrik RydgårdandClaude Opus 5.5 20063fe526 IR JITs: Name the fixed code routines that jumps go to in the disassembly
DescribeCodePtr() called everything in the fixed code other than a few
routines "fixedCode". It now uses the routine list the profiler has
(moved to the backend as GetAllFixedCodeLabels()), with an offset when
not at the start, so a block ends in "b dispatcherCheckCoreState".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 12:22:35 +02:00
Henrik RydgårdandClaude Opus 5.5 1d5e2689b5 JIT: Add --jit-profile, a sampling profiler for the CPU cores
The native IR JITs get the emulator thread's host PC sampled every 50 us (a
signal on macOS and Linux, SuspendThread on Windows), mapped to blocks, the
routines they call and host functions. The report has each hot block's MIPS,
IR and host code with the samples per host instruction. The IR interpreter's
block timing, previously behind IR_PROFILING, now runs on the same switch.
Both cost nothing when off.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 11:01:52 +02:00
Henrik RydgårdandClaude Opus 5.5 f3c69fc5d1 Remove FakeJit and the pre-IR JitBlockCache
FakeJit was the native JIT for architectures without one, but the config
already forces those onto the IR interpreter, so CreateNativeJit() now
returns that instead. The vertex decoder fallback no longer needs
FakeEmitter.

JitBlockCache was the block cache of the pre-IR JITs. Its header keeps
the debug interface types the IR block caches use. Also removes the
JitInterface link hooks only it called, and the JitState fields tied to
it. This fixes a null dereference in the ImDebugger memory section,
which read GetBlockCache(), always null with the IR JITs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 02:24:25 +02:00
Henrik RydgårdandClaude Sonnet 5 ffad0acea1 Plumb an explicit MIPSState *mips through the interpreter's Int_* handlers
All ~82 MIPSInt::Int_* functions (Interpreter.cpp/.h,
InterpreterVFPU.cpp/.h) now take an explicit MIPSState *mips instead
of reaching for the global currentMIPS internally, along with their
file-local helpers (DelayBranchTo, SkipLikely, ApplySwizzleS/T,
ApplyPrefixD/ST, RetainInvalidSwizzleST, EatPrefixes). MIPSInterpretFunc,
Interpret(), ExecInstruction()/InterpreterDispatch.cpp (regenerated),
and RunUntilFast() all thread mips through accordingly.

Deliberately left on currentMIPS for now: MIPSVFPUUtils.cpp's
ReadVector/WriteVector/ReadMatrix/WriteMatrix/VFPURewritePrefix -
these are shared with every JIT backend's compile-time VFPU code, so
parameterizing them would balloon this into a JIT-wide refactor. This
is a partial refactor; that's the next boundary to push on.

Several JIT backends (x86 Jit.cpp, ARM/ArmJit.cpp, ARM64/Arm64Jit.cpp,
x86/X64IRJit.cpp, RiscV/RiscVJit.cpp, LoongArch64/LoongArch64Jit.cpp,
ARM64/Arm64IRJit.cpp) bake the raw interpreter function pointer
directly into JIT-generated machine code as their "fall back to the
interpreter for this one op" mechanism, with only a single argument
register set up for the call. Rather than hand-editing register
allocation across four architectures that can't be build-tested here,
added MIPSInterpretTrampoline(MIPSOpcode op) - a 1-arg wrapper around
MIPSInterpret(currentMIPS, op) - and pointed all 7 such call sites at
it instead, leaving that codegen untouched. Two other call sites
(JitLogMiss, JitBranchLog) were plain C++ calls and just got the
extra argument directly.

Verified (Windows x64): PPSSPPWindows/PPSSPPHeadless/UnitTest all
build clean, 49/49 unit tests pass. `test.py -g --graphics=software`:
interpreter 312/314 (cpu/fpu/fpu is the pre-existing, unrelated
interpreter-vs-JIT denormal difference; gpu/rendertarget/copy passes
standalone, so was cross-test state bleed in the batch run, not a
regression), default JIT 314/314, jit-ir 313/314 (gpu/vertices/morph
is an expected difference from the vertex decoder taking a different
mode with this core change, not a bug).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SKhm9wKEQzRUsx9mTrrtQ
2026-08-12 14:02:19 +02:00
Henrik Rydgård ba148e5ec7 JIT/IRJit: Delete an old "function preloading" experiment
This caused some confusion while trying to debug #20502
2025-06-11 15:45:18 +02:00
Henrik Rydgård 85e7ff7ac3 Target->Native renaming. More intuitive (at least to me) 2024-07-22 01:24:34 +02:00
Henrik Rydgård 9d36a08ec4 Some renaming, remove a gross hack 2024-07-21 19:12:51 +02:00
Henrik Rydgård e01ca5b057 Logging API change (refactor) (#19324)
* Rename LogType to Log

* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.

* Mac/ARM64 buildfix

* Do the same with the hle result log macros

* Rename the log names to mixed case while at it.

* iOS buildfix

* Qt buildfix attempt, ARM32 buildfix
2024-07-14 14:42:59 +02:00
Henrik Rydgård 5526ef012c Store IR instructions in a large arena vector instead of loosely in each block. 2024-06-07 09:28:27 +02:00
Henrik Rydgård e75e7a0e43 Add an optimizeForInterpreter flag 2024-05-26 13:41:31 +02:00
Unknown W. Brackets 00c80cea6e irjit: Optimize offset logging during compile.
As I guessed, this was expensive.  using a vector and reserve isn't very.
It's nice to keep this before logBlocks_ is > 0, in case it's set mid
block.
2023-09-30 15:56:18 -07:00
Unknown W. Brackets 9b2fa46861 IR: Add mini native jit MIPS block profiler. 2023-09-24 23:04:29 -07:00
Henrik Rydgård 06a1f0b72c Merge pull request #18226 from unknownbrackets/x86-ir-breakpoints
x86jit: Improve memory breakpoint speed
2023-09-25 00:47:22 +02:00
Unknown W. Brackets 017d0d4b17 x86jit: Improve memory breakpoint speed.
This helps a lot compared to before.
2023-09-24 07:06:57 -07:00
Unknown W. Brackets 3e20a5802f x86jit: Describe constants better. 2023-09-24 06:46:42 -07:00
Unknown W. Brackets 1b756ff8c1 arm64jit: Add initial base for IR jit.
This works, but very slowly at this point.
2023-09-03 12:14:28 -07:00
Unknown W. Brackets b370a89ef2 x86jit: Reduce block link padding.
Reduces bloat a good bit.
2023-09-01 22:33:02 -07:00
Unknown W. Brackets c4d13e522b x86jit: Use a literal pool to avoid rip checks. 2023-08-28 23:11:46 -07:00
Unknown W. Brackets ee5381917a x86jit: Implement downcount in register. 2023-08-28 21:09:56 -07:00
Unknown W. Brackets 2e64abd2a0 x86jit: Improve some debug labels.
Helps when running a profiler that reads these.
2023-08-27 12:51:29 -07:00
Unknown W. Brackets bea74ba162 x86jit: Avoid negative offset warning. 2023-08-21 20:38:56 -07:00
Unknown W. Brackets 08ea31f405 x86jit: Improve debug disasm. 2023-08-20 22:28:54 -07:00
Unknown W. Brackets 4e3f3860f9 x86jit: Stub out op categories to files. 2023-08-20 22:28:54 -07:00
Unknown W. Brackets c491f701ba x86jit: Add initial IR-based jit backend.
It works, but pretty slow in some parts with everything stubbed.
2023-08-20 22:28:54 -07:00