Remove the replaced backend's interpreter-fallback glue

The yaps2 recompilers compile every EE opcode natively, so the
per-instruction interpreter fallback the previous arm64 backend relied
on is dead code: drop intExecuteOneInst (Interpreter.cpp/R5900.h) and
the AndroidEEOpHist fallback-opcode histogram. EEDiffVerify stays — its
per-op hooks are worth re-emitting from the new recompiler later.

Also hoist the Qt metatype declarations shared by moc'd headers into
QtMetaTypes.h: with the debugger sources now optional the autogen bucket
layout shifted, exposing a specialization-after-instantiation error when
moc_MainWindow preceded moc_QtHost in mocs_compilation.
This commit is contained in:
Brian Degenhardt
2026-07-19 10:32:53 -07:00
parent 3e077eff9b
commit b1dbb0af84
8 changed files with 40 additions and 69 deletions
+1
View File
@@ -38,6 +38,7 @@ target_sources(pcsx2-qt PRIVATE
Translations.cpp
QtHost.cpp
QtHost.h
QtMetaTypes.h
QtKeyCodes.cpp
QtProgressCallback.cpp
QtProgressCallback.h
+2
View File
@@ -36,6 +36,8 @@ namespace Achievements
enum class LoginRequestReason;
}
#include "QtMetaTypes.h"
namespace GameList
{
struct Entry;
+1 -6
View File
@@ -38,12 +38,7 @@ namespace Achievements
enum class LoginRequestReason;
}
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
Q_DECLARE_METATYPE(std::optional<bool>);
Q_DECLARE_METATYPE(GSRendererType);
Q_DECLARE_METATYPE(InputBindingKey);
Q_DECLARE_METATYPE(CDVD_SourceType);
Q_DECLARE_METATYPE(Achievements::LoginRequestReason);
#include "QtMetaTypes.h"
class EmuThread : public QThread
{
+36
View File
@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
// Q_DECLARE_METATYPE specializations shared by every moc'd header that mentions
// these types in a signal/slot. They must appear in a common header (not just
// QtHost.h): AUTOMOC compiles all moc_*.cpp files into one mocs_compilation.cpp
// TU, and a moc that instantiates QMetaTypeId<T> before another header's
// specialization is an "explicit specialization after instantiation" error —
// which moc comes first depends on the autogen bucket layout, so it can flip
// whenever the source list changes.
#include <memory>
#include <optional>
#include <QtCore/QMetaType>
#include "pcsx2/Config.h"
#include "pcsx2/Input/InputManager.h"
struct VMBootParameters;
enum class CDVD_SourceType : uint8_t;
namespace Achievements
{
enum class LoginRequestReason;
}
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
Q_DECLARE_METATYPE(std::optional<bool>);
Q_DECLARE_METATYPE(GSRendererType);
Q_DECLARE_METATYPE(InputBindingKey);
Q_DECLARE_METATYPE(CDVD_SourceType);
Q_DECLARE_METATYPE(Achievements::LoginRequestReason);
-29
View File
@@ -1,29 +0,0 @@
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "common/Pcsx2Types.h"
// Gated EE opcode histogram for diagnosing interpreter-fallback hotspots on the mac
// ARM64 backend. Counts how often each opcode runs through the two fallback paths:
// - STEP : block-terminating single-step (intExecuteOneInst) — the expensive one
// - INLINE : in-block interpreter call (recEmitInterpInline)
// Every ~8M recorded fallback ops the EE thread prints "@@ANDROID_EE_OPHIST@@" lines
// listing the hottest primary opcodes + SPECIAL/REGIMM/COP2/MMI sub-ops, then resets.
// EE-thread-only (no atomics). Default 0 = zero overhead; flip to 1 for a diag build.
#ifndef ARMSX2_ANDROID_EE_OPHIST
#define ARMSX2_ANDROID_EE_OPHIST 0
#endif
#if ARMSX2_ANDROID_EE_OPHIST
namespace AndroidEEOpHist
{
// path: 0 = STEP (single-step), 1 = INLINE (in-block interp).
void Record(int path, u32 op);
// Emit-time tally of natively-compiled trap ops (proves the trap codegen engaged).
void NoteTrapCompiled();
}
// Counting thunk emitted by recEmitInterpInline in place of the raw interp handler
// when the histogram is on: records cpuRegs.code on the INLINE path, then dispatches.
void recOphistInlineThunk();
#endif
-1
View File
@@ -1183,7 +1183,6 @@ if(ANDROID)
list(APPEND pcsx2Headers
VU1Fingerprint.h
EEDiffVerify.h
AndroidEEOpHist.h
AndroidPerfBuckets.h
PS1DrvTrace.h)
# Oboe is the Android audio backend consumed by Host/OboeAudioStream.cpp.
-32
View File
@@ -307,38 +307,6 @@ void intDoBranch(u32 target)
}
}
// Interpret exactly one guest instruction at cpuRegs.pc using the interpreter,
// then return. This is the recompiler's per-instruction fallback: the ARM64 EE
// rec dispatcher calls it for opcodes it cannot yet compile (likely branches,
// coprocessor ops, syscalls, traps, ...). It mirrors execI; for branch opcodes
// the interpreter's own branch functions handle the delay slot and PC redirect.
// We must flush the accrued cycle count here for EVERY op, branches included:
// intDoBranch/_doBranch_shared gate their flush on Cpu == &intCpu, so in rec
// context a taken branch flushes nothing — a guest poll loop made of just a
// branch (e.g. Burnout's `BC0F .; nop` CPCOND0 wait) would freeze cpuRegs.cycle
// and the pending event (DMAC completion) would never come due.
// It must NOT do the interpreter's fastjmp exit (intJmpBuf is not
// set up in rec context); the rec drives exits through its own event test.
void intExecuteOneInst()
{
const u32 thispc = cpuRegs.pc;
// Pre-increment PC: exception handlers and branch target math expect cpuRegs.pc
// to already point at the delay slot (matches execI).
cpuRegs.pc += 4;
cpuRegs.code = memRead32(thispc);
const OPCODE& opcode = GetCurrentInstruction();
cpuBlockCycles += opcode.cycles * (2 - ((cpuRegs.CP0.n.Config >> 18) & 0x1));
opcode.interpret();
// Unconditional: in rec context the interpreter's branch helpers skip their
// flush (intDoBranch is gated on Cpu == &intCpu), so this is the only place
// the accrued cycles reach cpuRegs.cycle. Always advances cycle by >= 1,
// guaranteeing forward progress for branch-only guest wait loops.
intUpdateCPUCycles();
}
void intSetBranch()
{
branch2 = /*cpuRegs.branch =*/ 1;
-1
View File
@@ -323,7 +323,6 @@ void intDoBranch(u32 target);
// Interpret a single instruction at cpuRegs.pc (recompiler per-opcode fallback).
// See the implementation in Interpreter.cpp for the contract.
void intExecuteOneInst();
// modules loaded at hardcoded addresses by the kernel
const u32 EEKERNEL_START = 0;