mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 18:59:04 +02:00
Kernel code's loads and stores may reach hardware registers, which only the interpreter handled, so the IR frontend sent every one of them (in kernel blocks, only run by the VSH boot) to it. They now become LoadKernel*/StoreKernel* IR ops (one per size, like the plain loads and stores), which check at run time whether the address is memory or a hardware register (MMIO). After constant propagation, ResolveKernelMemory turns the ones at a constant address that's plain memory into ordinary loads and stores, so only the hardware registers, and addresses only known at run time, stay checked. The native JITs run the two ops through their IR fallback. They're barriers, since a register access has side effects, but can't change the GPRs, so constants stay known across. The kernel mode check for MMIO moves to the interpreter, the only caller that can run user code there. TestMMIO covers the new paths and which accesses stay checked. Under --vsh, the JIT and the interpreter now make the same unhandled register accesses, in the same numbers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
25 lines
1.5 KiB
C
25 lines
1.5 KiB
C
#pragma once
|
|
|
|
#include "Core/MIPS/IR/IRInst.h"
|
|
|
|
typedef bool (*IRPassFunc)(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
|
|
// Block optimizer passes of varying usefulness.
|
|
bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool ReduceLoads(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool ReorderLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool MergeLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool ApplyMemoryValidation(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool ReduceVec4Flush(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
|
|
bool OptimizeLoadsAfterStores(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
// Kernel code's loads and stores at a constant address become plain ones where that's memory, so only
|
|
// hardware registers (and addresses only known when it runs) stay LoadKernel*/StoreKernel*.
|
|
bool ResolveKernelMemory(const IRWriter &in, IRWriter &out, const IROptions &opts);
|
|
bool OptimizeForInterpreter(const IRWriter &in, IRWriter &out, const IROptions &opts);
|