From a23bf56fb2cdce7280684ccee8886efc67a4d9e9 Mon Sep 17 00:00:00 2001 From: Merry Date: Sun, 21 Jan 2024 17:15:48 +0000 Subject: [PATCH] arm/dynarmic: Merge optimization configuration --- src/common/CMakeLists.txt | 1 + src/common/always_false.h | 16 ++++ src/core/CMakeLists.txt | 1 + src/core/arm/dynarmic/arm_dynarmic_32.cpp | 77 +-------------- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 76 +-------------- src/core/arm/dynarmic/dynarmic_settings.h | 108 ++++++++++++++++++++++ 6 files changed, 130 insertions(+), 149 deletions(-) create mode 100644 src/common/always_false.h create mode 100644 src/core/arm/dynarmic/dynarmic_settings.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 8c57d47c6f..c5ee28187d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(common STATIC address_space.h algorithm.h alignment.h + always_false.h announce_multiplayer_room.h assert.cpp assert.h diff --git a/src/common/always_false.h b/src/common/always_false.h new file mode 100644 index 0000000000..6058506f7a --- /dev/null +++ b/src/common/always_false.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Common { + +template +struct always_false { + static constexpr bool value = false; +}; + +template +inline constexpr bool always_false_v = false; + +} // namespace Common diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 16ddb5e909..a79740dfc3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -913,6 +913,7 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) arm/dynarmic/dynarmic_cp15.h arm/dynarmic/dynarmic_exclusive_monitor.cpp arm/dynarmic/dynarmic_exclusive_monitor.h + arm/dynarmic/dynarmic_settings.h hle/service/jit/jit_code_memory.cpp hle/service/jit/jit_code_memory.h hle/service/jit/jit_context.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 36478f7224..c077209086 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -6,6 +6,7 @@ #include "core/arm/dynarmic/arm_dynarmic_32.h" #include "core/arm/dynarmic/dynarmic_cp15.h" #include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" +#include "core/arm/dynarmic/dynarmic_settings.h" #include "core/core_timing.h" #include "core/hle/kernel/k_process.h" @@ -224,81 +225,7 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa config.code_cache_size = 8_MiB; } - // Safe optimizations - if (Settings::values.cpu_debug_mode) { - if (!Settings::values.cpuopt_page_tables) { - config.page_table = nullptr; - } - if (!Settings::values.cpuopt_block_linking) { - config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking; - } - if (!Settings::values.cpuopt_return_stack_buffer) { - config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer; - } - if (!Settings::values.cpuopt_fast_dispatcher) { - config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch; - } - if (!Settings::values.cpuopt_context_elimination) { - config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination; - } - if (!Settings::values.cpuopt_const_prop) { - config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp; - } - if (!Settings::values.cpuopt_misc_ir) { - config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt; - } - if (!Settings::values.cpuopt_reduce_misalign_checks) { - config.only_detect_misalignment_via_page_table_on_page_boundary = false; - } - if (!Settings::values.cpuopt_fastmem) { - config.fastmem_pointer = nullptr; - config.fastmem_exclusive_access = false; - } - if (!Settings::values.cpuopt_fastmem_exclusives) { - config.fastmem_exclusive_access = false; - } - if (!Settings::values.cpuopt_recompile_exclusives) { - config.recompile_on_exclusive_fastmem_failure = false; - } - if (!Settings::values.cpuopt_ignore_memory_aborts) { - config.check_halt_on_memory_access = true; - } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } - } + ConfigureOptimizationSettings(config); return std::make_unique(config); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index c811c8ad56..483c5aad0e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -5,6 +5,7 @@ #include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" #include "core/arm/dynarmic/dynarmic_exclusive_monitor.h" +#include "core/arm/dynarmic/dynarmic_settings.h" #include "core/core_timing.h" #include "core/hle/kernel/k_process.h" @@ -283,80 +284,7 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa config.code_cache_size = 8_MiB; } - // Safe optimizations - if (Settings::values.cpu_debug_mode) { - if (!Settings::values.cpuopt_page_tables) { - config.page_table = nullptr; - } - if (!Settings::values.cpuopt_block_linking) { - config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking; - } - if (!Settings::values.cpuopt_return_stack_buffer) { - config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer; - } - if (!Settings::values.cpuopt_fast_dispatcher) { - config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch; - } - if (!Settings::values.cpuopt_context_elimination) { - config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination; - } - if (!Settings::values.cpuopt_const_prop) { - config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp; - } - if (!Settings::values.cpuopt_misc_ir) { - config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt; - } - if (!Settings::values.cpuopt_reduce_misalign_checks) { - config.only_detect_misalignment_via_page_table_on_page_boundary = false; - } - if (!Settings::values.cpuopt_fastmem) { - config.fastmem_pointer = nullptr; - config.fastmem_exclusive_access = false; - } - if (!Settings::values.cpuopt_fastmem_exclusives) { - config.fastmem_exclusive_access = false; - } - if (!Settings::values.cpuopt_recompile_exclusives) { - config.recompile_on_exclusive_fastmem_failure = false; - } - if (!Settings::values.cpuopt_ignore_memory_aborts) { - config.check_halt_on_memory_access = true; - } - } else { - // Unsafe optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { - config.unsafe_optimizations = true; - if (Settings::values.cpuopt_unsafe_unfuse_fma) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - } - if (Settings::values.cpuopt_unsafe_reduce_fp_error) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; - } - if (Settings::values.cpuopt_unsafe_inaccurate_nan) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; - } - if (Settings::values.cpuopt_unsafe_fastmem_check) { - config.fastmem_address_space_bits = 64; - } - if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - } - - // Curated optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { - config.unsafe_optimizations = true; - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; - config.fastmem_address_space_bits = 64; - config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; - } - - // Paranoia mode for debugging optimizations - if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { - config.unsafe_optimizations = false; - config.optimizations = Dynarmic::no_optimizations; - } - } + ConfigureOptimizationSettings(config); return std::make_shared(config); } diff --git a/src/core/arm/dynarmic/dynarmic_settings.h b/src/core/arm/dynarmic/dynarmic_settings.h new file mode 100644 index 0000000000..7a5be50b39 --- /dev/null +++ b/src/core/arm/dynarmic/dynarmic_settings.h @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/always_false.h" +#include "common/assert.h" +#include "common/settings.h" + +namespace Dynarmic::A32 { +struct UserConfig; +} + +namespace Dynarmic::A64 { +struct UserConfig; +} + +namespace Core { + +template +void ConfigureOptimizationSettings(Config& config) { + // Safe optimizations + if (Settings::values.cpu_debug_mode) { + if (!Settings::values.cpuopt_page_tables) { + config.page_table = nullptr; + } + if (!Settings::values.cpuopt_block_linking) { + config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking; + } + if (!Settings::values.cpuopt_return_stack_buffer) { + config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer; + } + if (!Settings::values.cpuopt_fast_dispatcher) { + config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch; + } + if (!Settings::values.cpuopt_context_elimination) { + config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination; + } + if (!Settings::values.cpuopt_const_prop) { + config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp; + } + if (!Settings::values.cpuopt_misc_ir) { + config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt; + } + if (!Settings::values.cpuopt_reduce_misalign_checks) { + config.only_detect_misalignment_via_page_table_on_page_boundary = false; + } + if (!Settings::values.cpuopt_fastmem) { + config.fastmem_pointer = nullptr; + config.fastmem_exclusive_access = false; + } + if (!Settings::values.cpuopt_fastmem_exclusives) { + config.fastmem_exclusive_access = false; + } + if (!Settings::values.cpuopt_recompile_exclusives) { + config.recompile_on_exclusive_fastmem_failure = false; + } + if (!Settings::values.cpuopt_ignore_memory_aborts) { + config.check_halt_on_memory_access = true; + } + } else { + // Unsafe optimizations + if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) { + config.unsafe_optimizations = true; + if (Settings::values.cpuopt_unsafe_unfuse_fma) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + } + if (Settings::values.cpuopt_unsafe_reduce_fp_error) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; + } + if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + } + if (Settings::values.cpuopt_unsafe_inaccurate_nan) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + } + if (Settings::values.cpuopt_unsafe_ignore_global_monitor) { + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + } + } + + // Curated optimizations + if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) { + if constexpr (std::is_same_v) { + config.unsafe_optimizations = true; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + } else if constexpr (std::is_same_v) { + config.unsafe_optimizations = true; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; + config.fastmem_address_space_bits = 64; + config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor; + } else { + static_assert(Common::always_false_v); + } + } + + // Paranoia mode for debugging optimizations + if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) { + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; + } + } +} + +} // namespace Core