diff --git a/CMakeLists.txt b/CMakeLists.txt index 994bc184fa..411de4620b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -310,7 +310,6 @@ endif() if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX)) set(HAS_NCE 1) add_compile_definitions(HAS_NCE=1) - find_package(oaknut 2.0.1) endif() if (YUZU_ROOM) diff --git a/CMakeModules/Findsirit.cmake b/CMakeModules/Findsirit.cmake new file mode 100644 index 0000000000..83b81b09c5 --- /dev/null +++ b/CMakeModules/Findsirit.cmake @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +pkg_search_module(sirit QUIET IMPORTED_TARGET sirit) +find_package_handle_standard_args(sirit + REQUIRED_VARS sirit_LINK_LIBRARIES + VERSION_VAR sirit_VERSION +) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index dcafc8f97d..283da76743 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -10,7 +10,7 @@ "repo": "eden-emulator/sirit", "sha": "db1f1e8ab5", "hash": "73eb3a042848c63a10656545797e85f40d142009dfb7827384548a385e1e28e1ac72f42b25924ce530d58275f8638554281e884d72f9c7aaf4ed08690a414b05", - "find_args": "CONFIG", + "find_args": "MODULE", "options": [ "SIRIT_USE_SYSTEM_SPIRV_HEADERS ON" ] diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 96ea429e5a..7759ea6a21 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -32,6 +32,7 @@ add_library( atomic_ops.h bit_cast.h bit_field.h + bit_set.h bit_util.h bounded_threadsafe_queue.h cityhash.cpp diff --git a/src/common/bit_set.h b/src/common/bit_set.h new file mode 100644 index 0000000000..74754504be --- /dev/null +++ b/src/common/bit_set.h @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/alignment.h" +#include "common/bit_util.h" +#include "common/common_types.h" + +namespace Common { + +namespace impl { + +template +class BitSet { + +public: + constexpr BitSet() = default; + + constexpr void SetBit(size_t i) { + this->words[i / FlagsPerWord] |= GetBitMask(i % FlagsPerWord); + } + + constexpr void ClearBit(size_t i) { + this->words[i / FlagsPerWord] &= ~GetBitMask(i % FlagsPerWord); + } + + constexpr size_t CountLeadingZero() const { + for (size_t i = 0; i < NumWords; i++) { + if (this->words[i]) { + return FlagsPerWord * i + CountLeadingZeroImpl(this->words[i]); + } + } + return FlagsPerWord * NumWords; + } + + constexpr size_t GetNextSet(size_t n) const { + for (size_t i = (n + 1) / FlagsPerWord; i < NumWords; i++) { + Storage word = this->words[i]; + if (!IsAligned(n + 1, FlagsPerWord)) { + word &= GetBitMask(n % FlagsPerWord) - 1; + } + if (word) { + return FlagsPerWord * i + CountLeadingZeroImpl(word); + } + } + return FlagsPerWord * NumWords; + } + +private: + static_assert(std::is_unsigned_v); + static_assert(sizeof(Storage) <= sizeof(u64)); + + static constexpr size_t FlagsPerWord = BitSize(); + static constexpr size_t NumWords = AlignUp(N, FlagsPerWord) / FlagsPerWord; + + static constexpr auto CountLeadingZeroImpl(Storage word) { + return std::countl_zero(static_cast(word)) - + (BitSize() - FlagsPerWord); + } + + static constexpr Storage GetBitMask(size_t bit) { + return Storage(1) << (FlagsPerWord - 1 - bit); + } + + std::array words{}; +}; + +} // namespace impl + +template +using BitSet8 = impl::BitSet; + +template +using BitSet16 = impl::BitSet; + +template +using BitSet32 = impl::BitSet; + +template +using BitSet64 = impl::BitSet; + +} // namespace Common diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 11c217fce6..6b64ab7820 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1224,7 +1224,7 @@ if (HAS_NCE) arm/nce/patcher.h arm/nce/visitor_base.h ) - target_link_libraries(core PRIVATE merry::oaknut) + target_link_libraries(core PRIVATE merry::mcl merry::oaknut) endif() if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) diff --git a/src/core/arm/nce/patcher.h b/src/core/arm/nce/patcher.h index 31b122477f..7f54608e3f 100644 --- a/src/core/arm/nce/patcher.h +++ b/src/core/arm/nce/patcher.h @@ -27,11 +27,11 @@ template <> struct std::hash { size_t operator()(const PatchCacheKey& key) const { // Simple XOR hash of first few bytes - size_t hash_ = 0; + size_t hash = 0; for (size_t i = 0; i < key.module_id.size(); ++i) { - hash_ ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); + hash ^= static_cast(key.module_id[i]) << ((i % sizeof(size_t)) * 8); } - return hash_ ^ std::hash{}(key.offset); + return hash ^ std::hash{}(key.offset); } }; diff --git a/src/core/hle/kernel/k_priority_queue.h b/src/core/hle/kernel/k_priority_queue.h index 99347b5aef..26677ec65c 100644 --- a/src/core/hle/kernel/k_priority_queue.h +++ b/src/core/hle/kernel/k_priority_queue.h @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -8,12 +5,10 @@ #include #include -#include #include -#include -#include "common/alignment.h" #include "common/assert.h" +#include "common/bit_set.h" #include "common/common_types.h" #include "common/concepts.h" @@ -164,7 +159,7 @@ public: } if (m_queues[priority].PushBack(core, member)) { - m_available_priorities[core].set(std::size_t(priority)); + m_available_priorities[core].SetBit(priority); } } @@ -177,7 +172,7 @@ public: } if (m_queues[priority].PushFront(core, member)) { - m_available_priorities[core].set(std::size_t(priority)); + m_available_priorities[core].SetBit(priority); } } @@ -190,19 +185,14 @@ public: } if (m_queues[priority].Remove(core, member)) { - m_available_priorities[core].reset(std::size_t(priority)); + m_available_priorities[core].ClearBit(priority); } } constexpr Member* GetFront(s32 core) const { ASSERT(IsValidCore(core)); - const s32 priority = s32([](auto const& e) { - for (size_t i = 0; i < e.size(); ++i) - if (e[i]) - return i; - return e.size(); - }(m_available_priorities[core])); + const s32 priority = static_cast(m_available_priorities[core].CountLeadingZero()); if (priority <= LowestPriority) { return m_queues[priority].GetFront(core); } else { @@ -221,22 +211,16 @@ public: } } - template - constexpr size_t GetNextSet(std::bitset const& bit, size_t n) const { - for (size_t i = n + 1; i < bit.size(); i++) - if (bit[i]) - return i; - return bit.size(); - } - constexpr Member* GetNext(s32 core, const Member* member) const { ASSERT(IsValidCore(core)); Member* next = member->GetPriorityQueueEntry(core).GetNext(); if (next == nullptr) { - s32 priority = s32(GetNextSet(m_available_priorities[core], member->GetPriority())); - if (priority <= LowestPriority) + const s32 priority = static_cast( + m_available_priorities[core].GetNextSet(member->GetPriority())); + if (priority <= LowestPriority) { next = m_queues[priority].GetFront(core); + } } return next; } @@ -266,7 +250,7 @@ public: private: std::array m_queues{}; - std::array, NumCores> m_available_priorities{}; + std::array, NumCores> m_available_priorities{}; }; private: diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt index 58efcac747..9e6bd25913 100644 --- a/src/dynarmic/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/src/dynarmic/CMakeLists.txt @@ -374,7 +374,7 @@ endif() target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS}) target_link_libraries(dynarmic - PUBLIC + PRIVATE fmt::fmt merry::mcl )