aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2026-08-30 07:43:21 +0200
committercrueter <crueter@eden-emu.dev>2026-08-30 07:43:21 +0200
commitccf3de02cf83906c8da3d77ab66df051d5cb242f (patch)
treeb57eb7da5c32c57ffb697a3b6046e0f7ac3627b1 /src
parent1f03dee12645788d45c8727c7871a0d04b9bd0b4 (diff)
[dynarmic] optimise BlockOfCode to use less memory (#4303)
Signed-off-by: lizzie <lizzie@eden-emu.dev> - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- removes unique_ptr indireciton with argCallback (lmao) reorders jitState to be more cache friendly and yadda yadda removes redundant BlockOfCode& ptr on constantPool reorder blockOfCode to be btter update dynarmic because it removes 3kb worth of useless data :) Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4303 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src')
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp2
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp8
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/a32_jitstate.h24
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp2
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp8
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/a64_jitstate.h39
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp111
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/block_of_code.h21
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp13
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/constant_pool.h3
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/host_feature.h2
-rw-r--r--src/dynarmic/src/dynarmic/backend/x64/jitstate_info.h5
12 files changed, 87 insertions, 151 deletions
diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp
index a062ed6221..5c6a90e15a 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp
+++ b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp
@@ -247,7 +247,7 @@ void A32EmitX64::GenTerminalHandlers() {
calculate_location_descriptor();
code.mov(eax, dword[code.ABI_JIT_PTR + offsetof(A32JitState, rsb_ptr)]);
code.sub(eax, 1);
- code.and_(eax, u32(A32JitState::RSBPtrMask));
+ code.and_(eax, u32(A32JitState::RSB_PTR_MASK));
code.mov(dword[code.ABI_JIT_PTR + offsetof(A32JitState, rsb_ptr)], eax);
code.cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(A32JitState, rsb_location_descriptors) + rax * sizeof(u64)]);
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp
index 1a6d1205fb..72627b9e1a 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp
+++ b/src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp
@@ -37,9 +37,9 @@ using namespace Backend::X64;
static RunCodeCallbacks GenRunCodeCallbacks(A32::UserCallbacks* cb, CodePtr (*LookupBlock)(void* lookup_block_arg), void* arg, const A32::UserConfig& conf) {
return RunCodeCallbacks{
- std::make_unique<ArgCallback>(LookupBlock, reinterpret_cast<u64>(arg)),
- std::make_unique<ArgCallback>(Devirtualize<&A32::UserCallbacks::AddTicks>(cb)),
- std::make_unique<ArgCallback>(Devirtualize<&A32::UserCallbacks::GetTicksRemaining>(cb)),
+ ArgCallback(LookupBlock, reinterpret_cast<u64>(arg)),
+ ArgCallback(Devirtualize<&A32::UserCallbacks::AddTicks>(cb)),
+ ArgCallback(Devirtualize<&A32::UserCallbacks::GetTicksRemaining>(cb)),
conf.enable_cycle_counting,
};
}
@@ -79,7 +79,7 @@ struct Jit::Impl {
jit_interface->is_executing = true;
const CodePtr current_codeptr = [this] {
// RSB optimization
- const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A32JitState::RSBPtrMask;
+ const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A32JitState::RSB_PTR_MASK;
if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) {
jit_state.rsb_ptr = new_rsb_ptr;
return reinterpret_cast<CodePtr>(jit_state.rsb_codeptrs[new_rsb_ptr]);
diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_jitstate.h b/src/dynarmic/src/dynarmic/backend/x64/a32_jitstate.h
index c276ab0b8b..ad151e6092 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/a32_jitstate.h
+++ b/src/dynarmic/src/dynarmic/backend/x64/a32_jitstate.h
@@ -27,6 +27,9 @@ struct A32JitState {
A32JitState() { ResetRSB(); }
+ static constexpr std::size_t RSB_SIZE = 8; // MUST be a power of 2.
+ static constexpr std::size_t RSB_PTR_MASK = RSB_SIZE - 1;
+
std::array<u32, 16> Reg{}; // Current register file.
// TODO: Mode-specific register sets unimplemented.
@@ -36,8 +39,9 @@ struct A32JitState {
u32 cpsr_q = 0;
u32 cpsr_nzcv = 0;
u32 cpsr_jaifm = 0;
- u32 Cpsr() const;
- void SetCpsr(u32 cpsr);
+ u32 fpsr_exc = 0;
+ u32 fpsr_qc = 0;
+ u32 fpsr_nzcv = 0;
alignas(16) std::array<u32, 64> ExtReg{}; // Extension registers.
@@ -49,21 +53,19 @@ struct A32JitState {
// Exclusive state
u32 exclusive_state = 0;
- static constexpr std::size_t RSBSize = 8; // MUST be a power of 2.
- static constexpr std::size_t RSBPtrMask = RSBSize - 1;
u32 rsb_ptr = 0;
- std::array<u64, RSBSize> rsb_location_descriptors;
- std::array<u64, RSBSize> rsb_codeptrs;
- void ResetRSB();
+ std::array<u64, RSB_SIZE> rsb_location_descriptors;
+ std::array<u64, RSB_SIZE> rsb_codeptrs;
- u32 fpsr_exc = 0;
- u32 fpsr_qc = 0;
- u32 fpsr_nzcv = 0;
+ u32 Cpsr() const;
+ void SetCpsr(u32 cpsr);
+
+ void ResetRSB();
u32 Fpscr() const;
void SetFpscr(u32 FPSCR);
u64 GetUniqueHash() const noexcept {
- return (static_cast<u64>(upper_location_descriptor) << 32) | (static_cast<u64>(Reg[15]));
+ return (u64(upper_location_descriptor) << 32) | (u64(Reg[15]));
}
void TransferJitState(const A32JitState& src, bool reset_rsb) {
diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp
index 933008c258..71e5e62cd9 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp
+++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp
@@ -208,7 +208,7 @@ void A64EmitX64::GenTerminalHandlers() {
calculate_location_descriptor();
code.mov(eax, dword[code.ABI_JIT_PTR + offsetof(A64JitState, rsb_ptr)]);
code.sub(eax, 1);
- code.and_(eax, u32(A64JitState::RSBPtrMask));
+ code.and_(eax, u32(A64JitState::RSB_PTR_MASK));
code.mov(dword[code.ABI_JIT_PTR + offsetof(A64JitState, rsb_ptr)], eax);
code.cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(A64JitState, rsb_location_descriptors) + rax * sizeof(u64)]);
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp
index 9acaf3f9f6..bb072129e7 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp
+++ b/src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp
@@ -33,9 +33,9 @@ using namespace Backend::X64;
static RunCodeCallbacks GenRunCodeCallbacks(A64::UserCallbacks* cb, CodePtr (*LookupBlock)(void* lookup_block_arg), void* arg, const A64::UserConfig& conf) {
return RunCodeCallbacks{
- std::make_unique<ArgCallback>(LookupBlock, reinterpret_cast<u64>(arg)),
- std::make_unique<ArgCallback>(Devirtualize<&A64::UserCallbacks::AddTicks>(cb)),
- std::make_unique<ArgCallback>(Devirtualize<&A64::UserCallbacks::GetTicksRemaining>(cb)),
+ ArgCallback(LookupBlock, reinterpret_cast<u64>(arg)),
+ ArgCallback(Devirtualize<&A64::UserCallbacks::AddTicks>(cb)),
+ ArgCallback(Devirtualize<&A64::UserCallbacks::GetTicksRemaining>(cb)),
conf.enable_cycle_counting,
};
}
@@ -78,7 +78,7 @@ public:
// TODO: Check code alignment
const CodePtr current_code_ptr = [this] {
// RSB optimization
- const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSBPtrMask;
+ const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSB_PTR_MASK;
if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) {
jit_state.rsb_ptr = new_rsb_ptr;
return CodePtr(jit_state.rsb_codeptrs[new_rsb_ptr]);
diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_jitstate.h b/src/dynarmic/src/dynarmic/backend/x64/a64_jitstate.h
index 85ee1aa4b9..c3d8b04d1e 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/a64_jitstate.h
+++ b/src/dynarmic/src/dynarmic/backend/x64/a64_jitstate.h
@@ -29,18 +29,19 @@ struct A64JitState {
A64JitState() { ResetRSB(); }
+ // Exclusive state stuff
+ static constexpr u64 RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFF0ull;
+ // Return stack buffer
+ static constexpr size_t RSB_SIZE = 8; // MUST be a power of 2.
+ static constexpr size_t RSB_PTR_MASK = RSB_SIZE - 1;
+
std::array<u64, 31> reg{};
u64 sp = 0;
u64 pc = 0;
-
u32 cpsr_nzcv = 0;
-
- u32 GetPstate() const {
- return NZCV::FromX64(cpsr_nzcv);
- }
- void SetPstate(u32 new_pstate) {
- cpsr_nzcv = NZCV::ToX64(new_pstate);
- }
+ u32 fpsr_exc = 0;
+ u32 fpsr_qc = 0;
+ u32 fpcr = 0;
alignas(16) std::array<u64, 64> vec{}; // Extension registers.
@@ -50,29 +51,31 @@ struct A64JitState {
volatile u32 halt_reason = 0;
// Exclusive state
- static constexpr u64 RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFF0ull;
u8 exclusive_state = 0;
-
- static constexpr size_t RSBSize = 8; // MUST be a power of 2.
- static constexpr size_t RSBPtrMask = RSBSize - 1;
u32 rsb_ptr = 0;
- std::array<u64, RSBSize> rsb_location_descriptors;
- std::array<u64, RSBSize> rsb_codeptrs;
+ std::array<u64, RSB_SIZE> rsb_location_descriptors;
+ std::array<u64, RSB_SIZE> rsb_codeptrs;
+
+ u32 GetPstate() const {
+ return NZCV::FromX64(cpsr_nzcv);
+ }
+
+ void SetPstate(u32 new_pstate) {
+ cpsr_nzcv = NZCV::ToX64(new_pstate);
+ }
+
void ResetRSB() {
rsb_location_descriptors.fill(0xFFFFFFFFFFFFFFFFull);
rsb_codeptrs.fill(0);
}
- u32 fpsr_exc = 0;
- u32 fpsr_qc = 0;
- u32 fpcr = 0;
u32 GetFpcr() const;
u32 GetFpsr() const;
void SetFpcr(u32 value);
void SetFpsr(u32 value);
u64 GetUniqueHash() const noexcept {
- const u64 fpcr_u64 = static_cast<u64>(fpcr & A64::LocationDescriptor::fpcr_mask) << A64::LocationDescriptor::fpcr_shift;
+ const u64 fpcr_u64 = u64(fpcr & A64::LocationDescriptor::fpcr_mask) << A64::LocationDescriptor::fpcr_shift;
const u64 pc_u64 = pc & A64::LocationDescriptor::pc_mask;
return pc_u64 | fpcr_u64;
}
diff --git a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp
index f41bea6c83..24bfa799f2 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp
+++ b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp
@@ -61,73 +61,6 @@ namespace {
constexpr size_t CONSTANT_POOL_SIZE = 2 * 1024 * 1024;
constexpr size_t PRELUDE_COMMIT_SIZE = 16 * 1024 * 1024;
-class CustomXbyakAllocator : public Xbyak::Allocator {
-public:
-#ifdef _WIN32
- uint8_t* alloc(size_t size) override {
- void* p = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE);
- if (p == nullptr) {
- using Xbyak::Error;
- XBYAK_THROW(Xbyak::ERR_CANT_ALLOC);
- }
- return static_cast<uint8_t*>(p);
- }
-
- void free(uint8_t* p) override {
- VirtualFree(static_cast<void*>(p), 0, MEM_RELEASE);
- }
-
- bool useProtect() const override { return false; }
-#else
- static constexpr size_t DYNARMIC_PAGE_SIZE = 4096;
-
- // Can't subclass Xbyak::MmapAllocator because it is not a pure interface
- // and doesn't expose its construtor
- uint8_t* alloc(size_t size) override {
- // Waste a page to store the size
- size += DYNARMIC_PAGE_SIZE;
-
- int mode = MAP_PRIVATE;
-#if defined(MAP_ANONYMOUS)
- mode |= MAP_ANONYMOUS;
-#elif defined(MAP_ANON)
- mode |= MAP_ANON;
-#else
-# error "not supported"
-#endif
-#ifdef MAP_JIT
- mode |= MAP_JIT;
-#endif
- int prot = PROT_READ | PROT_WRITE;
-#ifdef PROT_MPROTECT
- // https://man.netbsd.org/mprotect.2 specifies that an mprotect() that is LESS
- // restrictive than the original mapping MUST fail
- prot |= PROT_MPROTECT(PROT_READ) | PROT_MPROTECT(PROT_WRITE) | PROT_MPROTECT(PROT_EXEC);
-#endif
- void* p = mmap(nullptr, size, prot, mode, -1, 0);
- if (p == MAP_FAILED) {
- using Xbyak::Error;
- XBYAK_THROW(Xbyak::ERR_CANT_ALLOC);
- }
- std::memcpy(p, &size, sizeof(size_t));
- return static_cast<uint8_t*>(p) + DYNARMIC_PAGE_SIZE;
- }
-
- void free(uint8_t* p) override {
- size_t size;
- std::memcpy(&size, p - DYNARMIC_PAGE_SIZE, sizeof(size_t));
- munmap(p - DYNARMIC_PAGE_SIZE, size);
- }
-
-# ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
- bool useProtect() const override { return false; }
-# endif
-#endif
-};
-
-// This is threadsafe as Xbyak::Allocator does not contain any state; it is a pure interface.
-CustomXbyakAllocator s_allocator;
-
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
void ProtectMemory(const void* base, size_t size, bool is_executable) {
# ifdef _WIN32
@@ -145,11 +78,9 @@ void ProtectMemory(const void* base, size_t size, bool is_executable) {
HostFeature GetHostFeatures() {
HostFeature features = {};
-
#ifdef DYNARMIC_ENABLE_CPU_FEATURE_DETECTION
using Cpu = Xbyak::util::Cpu;
- Xbyak::util::Cpu cpu_info;
-
+ Xbyak::util::Cpu cpu_info{};
if (cpu_info.has(Cpu::tSSSE3))
features |= HostFeature::SSSE3;
if (cpu_info.has(Cpu::tSSE41))
@@ -196,7 +127,6 @@ HostFeature GetHostFeatures() {
features |= HostFeature::GFNI;
if (cpu_info.has(Cpu::tWAITPKG))
features |= HostFeature::WAITPKG;
-
if (cpu_info.has(Cpu::tBMI2)) {
// BMI2 instructions such as pdep and pext have been very slow up until Zen 3.
// Check for Zen 3 or newer by its family (0x19).
@@ -214,7 +144,6 @@ HostFeature GetHostFeatures() {
}
}
#endif
-
return features;
}
@@ -233,23 +162,27 @@ bool IsUnderRosetta() {
} // anonymous namespace
+BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function<void(BlockOfCode&)> rcp)
+ : Xbyak::CodeGenerator(total_code_size
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
-static const auto default_cg_mode = Xbyak::DontSetProtectRWE;
+ , Xbyak::DontSetProtectRWE
#else
-static const auto default_cg_mode = nullptr; //Allow RWE
+ , nullptr //Allow RWE
#endif
-
-BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function<void(BlockOfCode&)> rcp)
- : Xbyak::CodeGenerator(total_code_size, default_cg_mode, &s_allocator)
- , cb(std::move(cb))
- , jsi(jsi)
- , constant_pool(*this, CONSTANT_POOL_SIZE)
- , host_features(GetHostFeatures()) {
+ , nullptr)
+ , constant_pool(*this, CONSTANT_POOL_SIZE)
+ , jsi(jsi)
+ , cb(std::move(cb))
+{
EnableWriting();
EnsureMemoryCommitted(PRELUDE_COMMIT_SIZE);
GenRunCode(rcp);
}
+bool BlockOfCode::HasHostFeature(HostFeature feature) const noexcept {
+ return (GetHostFeatures() & feature) == feature;
+}
+
void BlockOfCode::PreludeComplete() {
prelude_complete = true;
code_begin = getCurr();
@@ -341,7 +274,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
mov(rbx, ABI_PARAM2); // save temporarily in non-volatile register
if (cb.enable_cycle_counting) {
- cb.GetTicksRemaining->EmitCall(*this);
+ cb.GetTicksRemaining.EmitCall(*this);
mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], ABI_RETURN);
mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], ABI_RETURN);
}
@@ -388,7 +321,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0);
jng(return_to_caller);
}
- cb.LookupBlock->EmitCall(*this);
+ cb.LookupBlock.EmitCall(*this);
jmp(ABI_RETURN);
align();
@@ -401,7 +334,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
jng(return_to_caller_mxcsr_already_exited);
}
SwitchMxcsrOnEntry();
- cb.LookupBlock->EmitCall(*this);
+ cb.LookupBlock.EmitCall(*this);
jmp(ABI_RETURN);
align();
@@ -415,7 +348,7 @@ void BlockOfCode::GenRunCode(std::function<void(BlockOfCode&)> rcp) {
L(return_to_caller_mxcsr_already_exited);
if (cb.enable_cycle_counting) {
- cb.AddTicks->EmitCall(*this, [this](RegList param) {
+ cb.AddTicks.EmitCall(*this, [this](RegList param) {
mov(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]);
sub(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]);
});
@@ -455,18 +388,18 @@ void BlockOfCode::UpdateTicks() {
return;
}
- cb.AddTicks->EmitCall(*this, [this](RegList param) {
+ cb.AddTicks.EmitCall(*this, [this](RegList param) {
mov(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)]);
sub(param[0], qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)]);
});
- cb.GetTicksRemaining->EmitCall(*this);
+ cb.GetTicksRemaining.EmitCall(*this);
mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_to_run)], ABI_RETURN);
mov(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], ABI_RETURN);
}
void BlockOfCode::LookupBlock() {
- cb.LookupBlock->EmitCall(*this);
+ cb.LookupBlock.EmitCall(*this);
}
void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) {
@@ -520,7 +453,7 @@ void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) {
}
Xbyak::Address BlockOfCode::Const(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) {
- return constant_pool.GetConstant(frame, lower, upper);
+ return constant_pool.GetConstant(*this, frame, lower, upper);
}
CodePtr BlockOfCode::GetCodeBegin() const {
diff --git a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h
index eaeedf85af..20012a070f 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h
+++ b/src/dynarmic/src/dynarmic/backend/x64/block_of_code.h
@@ -31,9 +31,9 @@ namespace Dynarmic::Backend::X64 {
using CodePtr = const void*;
struct RunCodeCallbacks {
- std::unique_ptr<Callback> LookupBlock;
- std::unique_ptr<Callback> AddTicks;
- std::unique_ptr<Callback> GetTicksRemaining;
+ ArgCallback LookupBlock;
+ ArgCallback AddTicks;
+ ArgCallback GetTicksRemaining;
bool enable_cycle_counting;
};
@@ -166,27 +166,24 @@ public:
JitStateInfo GetJitStateInfo() const { return jsi; }
- bool HasHostFeature(HostFeature feature) const {
- return (host_features & feature) == feature;
- }
+ bool HasHostFeature(HostFeature feature) const noexcept;
private:
using RunCodeFuncType = HaltReason (*)(void*, CodePtr);
static constexpr size_t MXCSR_ALREADY_EXITED = 1 << 0;
static constexpr size_t FORCE_RETURN = 1 << 1;
- RunCodeCallbacks cb;
+ ConstantPool constant_pool;
JitStateInfo jsi;
+ std::array<const void*, 4> return_from_run_code;
+ RunCodeFuncType run_code = nullptr;
+ RunCodeFuncType step_code = nullptr;
+ RunCodeCallbacks cb;
CodePtr code_begin = nullptr;
#ifdef _WIN32
size_t committed_size = 0;
#endif
- ConstantPool constant_pool;
- RunCodeFuncType run_code = nullptr;
- RunCodeFuncType step_code = nullptr;
- std::array<const void*, 4> return_from_run_code;
bool prelude_complete = false;
- const HostFeature host_features;
void GenRunCode(std::function<void(BlockOfCode&)> rcp);
};
diff --git a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp
index e2b8c94148..8782ab0c73 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp
+++ b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp
@@ -16,8 +16,7 @@
namespace Dynarmic::Backend::X64 {
ConstantPool::ConstantPool(BlockOfCode& code, size_t size)
- : code(code)
- , insertion_point(0)
+ : insertion_point(0)
{
code.EnsureMemoryCommitted(align_size + size);
code.int3();
@@ -25,17 +24,17 @@ ConstantPool::ConstantPool(BlockOfCode& code, size_t size)
pool = std::span<ConstantT>(reinterpret_cast<ConstantT*>(code.AllocateFromCodeSpace(size)), size / align_size);
}
-Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) {
+Xbyak::Address ConstantPool::GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper) {
const auto constant = ConstantT(lower, upper);
- auto iter = constant_info.find(constant);
- if (iter == constant_info.end()) {
+ auto it = constant_info.find(constant);
+ if (it == constant_info.end()) {
ASSERT(insertion_point < pool.size());
ConstantT& target_constant = pool[insertion_point];
target_constant = constant;
- iter = constant_info.insert({constant, &target_constant}).first;
+ it = constant_info.insert({constant, &target_constant}).first;
++insertion_point;
}
- return frame[code.rip + iter->second];
+ return frame[code.rip + it->second];
}
} // namespace Dynarmic::Backend::X64
diff --git a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h
index 79e57fc78c..36b2ac633e 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h
+++ b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.h
@@ -29,7 +29,7 @@ class ConstantPool final {
public:
ConstantPool(BlockOfCode& code, size_t size);
- Xbyak::Address GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0);
+ Xbyak::Address GetConstant(BlockOfCode& code, const Xbyak::AddressFrame& frame, u64 lower, u64 upper = 0);
private:
static constexpr size_t align_size = 16; // bytes
@@ -45,7 +45,6 @@ private:
ankerl::unordered_dense::map<ConstantT, void*, ConstantHash> constant_info;
std::span<ConstantT> pool;
- BlockOfCode& code;
std::size_t insertion_point;
};
diff --git a/src/dynarmic/src/dynarmic/backend/x64/host_feature.h b/src/dynarmic/src/dynarmic/backend/x64/host_feature.h
index 019a36635b..3cd08362a0 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/host_feature.h
+++ b/src/dynarmic/src/dynarmic/backend/x64/host_feature.h
@@ -12,7 +12,7 @@
namespace Dynarmic::Backend::X64 {
-enum class HostFeature : u64 {
+enum class HostFeature : u32 {
SSSE3 = 1ULL << 0,
SSE41 = 1ULL << 1,
SSE42 = 1ULL << 2,
diff --git a/src/dynarmic/src/dynarmic/backend/x64/jitstate_info.h b/src/dynarmic/src/dynarmic/backend/x64/jitstate_info.h
index 654b3f0400..83c1d2e126 100644
--- a/src/dynarmic/src/dynarmic/backend/x64/jitstate_info.h
+++ b/src/dynarmic/src/dynarmic/backend/x64/jitstate_info.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@@ -15,7 +18,7 @@ struct JitStateInfo {
: offsetof_guest_MXCSR(offsetof(JitStateType, guest_MXCSR))
, offsetof_asimd_MXCSR(offsetof(JitStateType, asimd_MXCSR))
, offsetof_rsb_ptr(offsetof(JitStateType, rsb_ptr))
- , rsb_ptr_mask(JitStateType::RSBPtrMask)
+ , rsb_ptr_mask(JitStateType::RSB_PTR_MASK)
, offsetof_rsb_location_descriptors(offsetof(JitStateType, rsb_location_descriptors))
, offsetof_rsb_codeptrs(offsetof(JitStateType, rsb_codeptrs))
, offsetof_cpsr_nzcv(offsetof(JitStateType, cpsr_nzcv))