diff options
| author | lizzie <lizzie@eden-emu.dev> | 2026-05-15 22:07:45 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-05-15 22:07:45 +0200 |
| commit | 2f0f8a979c88b1ded8b5cce9f9bee1a59bb2508c (patch) | |
| tree | ab83030366f04aca746857d8c4275dd038a31fe1 /src/dynarmic | |
| parent | 413c7543ba25407f79226ba5e3f2f88d0ae63501 (diff) | |
[dynarmic, macroHLE] Use faster ankerl for xbyak maps (#3716)
the nominal std::unordered_map<> isn't enough to warrant it's continued usage in xbyak internal structures, thus using ankerl should greatly remove a lot of indirection/stdc++ specific overhead from the usually poorly performant std::unordered_map
Both dynarmic and macroHLE should benefit greatly from a less-stupid unordered_dense
This should speedup both CPU and shader compilation latency (NOT BY A GREAT MARGIN) just enough to make loading zones in ToTK less horrific
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3716
Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src/dynarmic')
| -rw-r--r-- | src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp | 4 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/backend/x64/abi.cpp | 10 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp | 10 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/backend/x64/hostloc.h | 2 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/backend/x64/xbyak.h | 14 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp | 6 | ||||
| -rw-r--r-- | src/dynarmic/tests/x64_cpu_info.cpp | 5 |
7 files changed, 25 insertions, 26 deletions
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 cf9dab4034..53381aa1df 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -224,7 +224,7 @@ void A64EmitX64::GenTerminalHandlers() { terminal_handler_fast_dispatch_hint = code.getCurr<const void*>(); calculate_location_descriptor(); code.L(rsb_cache_miss); - code.mov(r8, reinterpret_cast<u64>(fast_dispatch_table.data())); + code.mov(r8, u64(fast_dispatch_table.data())); //code.mov(r12, qword[code.ABI_JIT_PTR + offsetof(A64JitState, pc)]); code.mov(r12, rbx); if (code.HasHostFeature(HostFeature::SSE42)) { @@ -244,7 +244,7 @@ void A64EmitX64::GenTerminalHandlers() { code.align(); fast_dispatch_table_lookup = code.getCurr<FastDispatchEntry& (*)(u64)>(); - code.mov(code.ABI_PARAM2, reinterpret_cast<u64>(fast_dispatch_table.data())); + code.mov(code.ABI_PARAM2, u64(fast_dispatch_table.data())); if (code.HasHostFeature(HostFeature::SSE42)) { code.crc32(code.ABI_PARAM1, code.ABI_PARAM2); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp index 5d2ee735f3..59ecc974f7 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/abi.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/abi.cpp @@ -26,7 +26,7 @@ struct FrameInfo { }; static_assert(ABI_SHADOW_SPACE <= 32); -static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms, size_t frame_size) { +static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms, size_t frame_size) noexcept { // We are initially 8 byte aligned because the return value is pushed onto an aligned stack after a call. const size_t rsp_alignment = (num_gprs % 2 == 0) ? 8 : 0; const size_t total_xmm_size = num_xmms * XMM_SIZE; @@ -40,7 +40,7 @@ static FrameInfo CalculateFrameInfo(const size_t num_gprs, const size_t num_xmms }; } -void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { +static void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> regs) noexcept { using namespace Xbyak::util; const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); @@ -65,7 +65,7 @@ void ABI_PushRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, } } -void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> const& regs) { +static void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, const size_t frame_size, std::bitset<32> regs) noexcept { using namespace Xbyak::util; const size_t num_gprs = (ABI_ALL_GPRS & regs).count(); @@ -107,13 +107,13 @@ void ABI_PopCallerSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size // Windows ABI registers are not in the same allocation algorithm as unix's void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { - std::bitset<32> regs = ABI_ALL_CALLER_SAVE; + auto regs = ABI_ALL_CALLER_SAVE; regs.reset(size_t(exception)); ABI_PushRegistersAndAdjustStack(code, 0, regs); } void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { - std::bitset<32> regs = ABI_ALL_CALLER_SAVE; + auto regs = ABI_ALL_CALLER_SAVE; regs.reset(size_t(exception)); ABI_PopRegistersAndAdjustStack(code, 0, regs); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp index 127149a29e..e2b8c94148 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/constant_pool.cpp @@ -6,23 +6,23 @@ * SPDX-License-Identifier: 0BSD */ -#include "dynarmic/backend/x64/constant_pool.h" - #include <cstring> #include "common/assert.h" #include "dynarmic/backend/x64/block_of_code.h" +#include "dynarmic/backend/x64/constant_pool.h" namespace Dynarmic::Backend::X64 { ConstantPool::ConstantPool(BlockOfCode& code, size_t size) - : code(code), insertion_point(0) { + : code(code) + , insertion_point(0) +{ code.EnsureMemoryCommitted(align_size + size); code.int3(); code.align(align_size); - pool = std::span<ConstantT>( - reinterpret_cast<ConstantT*>(code.AllocateFromCodeSpace(size)), size / align_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) { diff --git a/src/dynarmic/src/dynarmic/backend/x64/hostloc.h b/src/dynarmic/src/dynarmic/backend/x64/hostloc.h index 7191a0ceba..d62090d612 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/hostloc.h +++ b/src/dynarmic/src/dynarmic/backend/x64/hostloc.h @@ -8,8 +8,6 @@ #pragma once #include <bitset> -#include <xbyak/xbyak.h> - #include "common/assert.h" #include "common/common_types.h" #include "dynarmic/backend/x64/xbyak.h" diff --git a/src/dynarmic/src/dynarmic/backend/x64/xbyak.h b/src/dynarmic/src/dynarmic/backend/x64/xbyak.h index ee74794fb4..38401678e6 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/xbyak.h +++ b/src/dynarmic/src/dynarmic/backend/x64/xbyak.h @@ -3,13 +3,11 @@ #pragma once -#include <unordered_map> -#include <unordered_set> - -// TODO: Defining this crashes e v e r y t h i n g -// #define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set -// #define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map -// #define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap - +// You must ensure this matches with src/common/x64/xbyak.h on root dir +#include <ankerl/unordered_dense.h> +#include <boost/unordered_map.hpp> +#define XBYAK_STD_UNORDERED_SET ankerl::unordered_dense::set +#define XBYAK_STD_UNORDERED_MAP ankerl::unordered_dense::map +#define XBYAK_STD_UNORDERED_MULTIMAP boost::unordered_multimap #include <xbyak/xbyak.h> #include <xbyak/xbyak_util.h> diff --git a/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp b/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp index d920f2d900..7c322050c3 100644 --- a/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp +++ b/src/dynarmic/src/dynarmic/common/fp/op/FPToFixed.cpp @@ -78,7 +78,7 @@ u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, Rou } // Detect Overflow - const int min_exponent_for_overflow = static_cast<int>(ibits) - static_cast<int>(mcl::bit::highest_set_bit(value.mantissa + (round_up ? Safe::LogicalShiftRight<u64>(1, exponent) : 0))) - (unsigned_ ? 0 : 1); + const int min_exponent_for_overflow = int(ibits) - int(mcl::bit::highest_set_bit(value.mantissa + (round_up ? Safe::LogicalShiftRight<u64>(1, exponent) : 0))) - (unsigned_ ? 0 : 1); if (exponent >= min_exponent_for_overflow) { // Positive overflow if (unsigned_ || !sign) { @@ -87,10 +87,10 @@ u64 FPToFixed(size_t ibits, FPT op, size_t fbits, bool unsigned_, FPCR fpcr, Rou } // Negative overflow - const u64 min_value = Safe::Negate<u64>(static_cast<u64>(1) << (ibits - 1)); + const u64 min_value = Safe::Negate<u64>(u64(1) << (ibits - 1)); if (!(exponent == min_exponent_for_overflow && int_result == min_value)) { FPProcessException(FPExc::InvalidOp, fpcr, fpsr); - return static_cast<u64>(1) << (ibits - 1); + return u64(1) << (ibits - 1); } } diff --git a/src/dynarmic/tests/x64_cpu_info.cpp b/src/dynarmic/tests/x64_cpu_info.cpp index 8e67f0fc39..a33d8c013f 100644 --- a/src/dynarmic/tests/x64_cpu_info.cpp +++ b/src/dynarmic/tests/x64_cpu_info.cpp @@ -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) 2020 MerryMage * SPDX-License-Identifier: 0BSD @@ -11,7 +14,7 @@ #include <utility> #include <catch2/catch_test_macros.hpp> -#include <xbyak/xbyak_util.h> +#include "dynarmic/backend/x64/xbyak.h" TEST_CASE("Host CPU supports", "[a64]") { using Cpu = Xbyak::util::Cpu; |
