mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-03 13:01:55 +01:00
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>
37 lines
1.1 KiB
C++
37 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Core/Core.h"
|
|
#include "Core/MemMap.h"
|
|
|
|
class MIPSState;
|
|
struct IRInst;
|
|
|
|
u32 IRRunBreakpoint(u32 pc);
|
|
u32 IRRunMemCheck(u32 pc, u32 addr);
|
|
// A LoadKernel*/StoreKernel* (op) to an address the native JITs don't access directly: a hardware
|
|
// register, or not memory at all.
|
|
u32 IRRunKernelLoad(MIPSState *mips, u32 addr, u32 op);
|
|
void IRRunKernelStore(MIPSState *mips, u32 addr, u32 value, u32 op);
|
|
|
|
template <uint32_t alignment>
|
|
u32 RunValidateAddress(u32 pc, u32 addr, u32 isWrite) {
|
|
static_assert(alignment <= 16);
|
|
const auto toss = [&](MemoryExceptionType t) {
|
|
Core_MemoryException(addr, alignment, pc, t);
|
|
return coreState != CORE_RUNNING_CPU ? 1 : 0;
|
|
};
|
|
|
|
if (!Memory::IsValidNAlignedAddress<alignment>(addr)) {
|
|
MemoryExceptionType t = isWrite == 1 ? MemoryExceptionType::WRITE_WORD : MemoryExceptionType::READ_WORD;
|
|
if constexpr (alignment > 4)
|
|
t = isWrite ? MemoryExceptionType::WRITE_BLOCK : MemoryExceptionType::READ_BLOCK;
|
|
return toss(t);
|
|
}
|
|
|
|
if constexpr (alignment > 1)
|
|
if ((addr & (alignment - 1)) != 0)
|
|
return toss(MemoryExceptionType::ALIGNMENT);
|
|
return 0;
|
|
}
|