Просмотр исходного кода

common/bit_util: Replace CLZ/CTZ operations with standardized ones

Makes for less code that we need to maintain.
Lioncash 5 лет назад
Родитель
Сommit
8620de6b20

+ 0 - 76
src/common/bit_util.h

@@ -21,82 +21,6 @@ template <typename T>
     return sizeof(T) * CHAR_BIT;
 }
 
-#ifdef _MSC_VER
-[[nodiscard]] inline u32 CountLeadingZeroes32(u32 value) {
-    unsigned long leading_zero = 0;
-
-    if (_BitScanReverse(&leading_zero, value) != 0) {
-        return 31 - leading_zero;
-    }
-
-    return 32;
-}
-
-[[nodiscard]] inline u32 CountLeadingZeroes64(u64 value) {
-    unsigned long leading_zero = 0;
-
-    if (_BitScanReverse64(&leading_zero, value) != 0) {
-        return 63 - leading_zero;
-    }
-
-    return 64;
-}
-#else
-[[nodiscard]] inline u32 CountLeadingZeroes32(u32 value) {
-    if (value == 0) {
-        return 32;
-    }
-
-    return static_cast<u32>(__builtin_clz(value));
-}
-
-[[nodiscard]] inline u32 CountLeadingZeroes64(u64 value) {
-    if (value == 0) {
-        return 64;
-    }
-
-    return static_cast<u32>(__builtin_clzll(value));
-}
-#endif
-
-#ifdef _MSC_VER
-[[nodiscard]] inline u32 CountTrailingZeroes32(u32 value) {
-    unsigned long trailing_zero = 0;
-
-    if (_BitScanForward(&trailing_zero, value) != 0) {
-        return trailing_zero;
-    }
-
-    return 32;
-}
-
-[[nodiscard]] inline u32 CountTrailingZeroes64(u64 value) {
-    unsigned long trailing_zero = 0;
-
-    if (_BitScanForward64(&trailing_zero, value) != 0) {
-        return trailing_zero;
-    }
-
-    return 64;
-}
-#else
-[[nodiscard]] inline u32 CountTrailingZeroes32(u32 value) {
-    if (value == 0) {
-        return 32;
-    }
-
-    return static_cast<u32>(__builtin_ctz(value));
-}
-
-[[nodiscard]] inline u32 CountTrailingZeroes64(u64 value) {
-    if (value == 0) {
-        return 64;
-    }
-
-    return static_cast<u32>(__builtin_ctzll(value));
-}
-#endif
-
 #ifdef _MSC_VER
 
 [[nodiscard]] inline u32 MostSignificantBit32(const u32 value) {

+ 2 - 2
src/core/hle/kernel/k_priority_queue.h

@@ -8,11 +8,11 @@
 #pragma once
 
 #include <array>
+#include <bit>
 #include <concepts>
 
 #include "common/assert.h"
 #include "common/bit_set.h"
-#include "common/bit_util.h"
 #include "common/common_types.h"
 #include "common/concepts.h"
 
@@ -268,7 +268,7 @@ private:
     }
 
     constexpr s32 GetNextCore(u64& affinity) {
-        const s32 core = Common::CountTrailingZeroes64(affinity);
+        const s32 core = std::countr_zero(affinity);
         ClearAffinityBit(affinity, core);
         return core;
     }

+ 5 - 3
src/core/hle/kernel/k_scheduler.cpp

@@ -5,6 +5,8 @@
 // This file references various implementation details from Atmosphere, an open-source firmware for
 // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
 
+#include <bit>
+
 #include "common/assert.h"
 #include "common/bit_util.h"
 #include "common/fiber.h"
@@ -31,12 +33,12 @@ static void IncrementScheduledCount(Kernel::Thread* thread) {
 
 void KScheduler::RescheduleCores(KernelCore& kernel, u64 cores_pending_reschedule,
                                  Core::EmuThreadHandle global_thread) {
-    u32 current_core = global_thread.host_handle;
+    const u32 current_core = global_thread.host_handle;
     bool must_context_switch = global_thread.guest_handle != InvalidHandle &&
                                (current_core < Core::Hardware::NUM_CPU_CORES);
 
     while (cores_pending_reschedule != 0) {
-        u32 core = Common::CountTrailingZeroes64(cores_pending_reschedule);
+        const auto core = static_cast<u32>(std::countr_zero(cores_pending_reschedule));
         ASSERT(core < Core::Hardware::NUM_CPU_CORES);
         if (!must_context_switch || core != current_core) {
             auto& phys_core = kernel.PhysicalCore(core);
@@ -109,7 +111,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
 
     // Idle cores are bad. We're going to try to migrate threads to each idle core in turn.
     while (idle_cores != 0) {
-        u32 core_id = Common::CountTrailingZeroes64(idle_cores);
+        const auto core_id = static_cast<u32>(std::countr_zero(idle_cores));
         if (Thread* suggested = priority_queue.GetSuggestedFront(core_id); suggested != nullptr) {
             s32 migration_candidates[Core::Hardware::NUM_CPU_CORES];
             size_t num_candidates = 0;

+ 2 - 2
src/core/hle/kernel/memory/page_heap.h

@@ -8,11 +8,11 @@
 #pragma once
 
 #include <array>
+#include <bit>
 #include <vector>
 
 #include "common/alignment.h"
 #include "common/assert.h"
-#include "common/bit_util.h"
 #include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "core/hle/kernel/memory/memory_types.h"
@@ -105,7 +105,7 @@ private:
                         ASSERT(depth == 0);
                         return -1;
                     }
-                    offset = offset * 64 + Common::CountTrailingZeroes64(v);
+                    offset = offset * 64 + static_cast<u32>(std::countr_zero(v));
                     ++depth;
                 } while (depth < static_cast<s32>(used_depths));
 

+ 3 - 1
src/core/hle/kernel/process_capability.cpp

@@ -2,6 +2,8 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <bit>
+
 #include "common/bit_util.h"
 #include "common/logging/log.h"
 #include "core/hle/kernel/errors.h"
@@ -60,7 +62,7 @@ constexpr CapabilityType GetCapabilityType(u32 value) {
 
 u32 GetFlagBitOffset(CapabilityType type) {
     const auto value = static_cast<u32>(type);
-    return static_cast<u32>(Common::BitSize<u32>() - Common::CountLeadingZeroes32(value));
+    return static_cast<u32>(Common::BitSize<u32>() - static_cast<u32>(std::countl_zero(value)));
 }
 
 } // Anonymous namespace

+ 0 - 1
src/tests/CMakeLists.txt

@@ -1,6 +1,5 @@
 add_executable(tests
     common/bit_field.cpp
-    common/bit_utils.cpp
     common/fibers.cpp
     common/param_package.cpp
     common/ring_buffer.cpp

+ 0 - 23
src/tests/common/bit_utils.cpp

@@ -1,23 +0,0 @@
-// Copyright 2017 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <catch2/catch.hpp>
-#include <math.h>
-#include "common/bit_util.h"
-
-namespace Common {
-
-TEST_CASE("BitUtils::CountTrailingZeroes", "[common]") {
-    REQUIRE(Common::CountTrailingZeroes32(0) == 32);
-    REQUIRE(Common::CountTrailingZeroes64(0) == 64);
-    REQUIRE(Common::CountTrailingZeroes32(9) == 0);
-    REQUIRE(Common::CountTrailingZeroes32(8) == 3);
-    REQUIRE(Common::CountTrailingZeroes32(0x801000) == 12);
-    REQUIRE(Common::CountTrailingZeroes64(9) == 0);
-    REQUIRE(Common::CountTrailingZeroes64(8) == 3);
-    REQUIRE(Common::CountTrailingZeroes64(0x801000) == 12);
-    REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == 36);
-}
-
-} // namespace Common

+ 2 - 2
src/video_core/cdma_pusher.cpp

@@ -18,10 +18,10 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#include <bit>
 #include "command_classes/host1x.h"
 #include "command_classes/nvdec.h"
 #include "command_classes/vic.h"
-#include "common/bit_util.h"
 #include "video_core/cdma_pusher.h"
 #include "video_core/command_classes/nvdec_common.h"
 #include "video_core/engines/maxwell_3d.h"
@@ -56,7 +56,7 @@ void CDmaPusher::Step() {
 
     for (const u32 value : values) {
         if (mask != 0) {
-            const u32 lbs = Common::CountTrailingZeroes32(mask);
+            const auto lbs = static_cast<u32>(std::countr_zero(mask));
             mask &= ~(1U << lbs);
             ExecuteCommand(static_cast<u32>(offset + lbs), value);
             continue;

+ 1 - 1
src/video_core/cdma_pusher.h

@@ -126,7 +126,7 @@ private:
 
     s32 count{};
     s32 offset{};
-    s32 mask{};
+    u32 mask{};
     bool incrementing{};
 
     // Queue of command lists to be processed

+ 2 - 2
src/video_core/command_classes/codecs/h264.cpp

@@ -19,7 +19,7 @@
 //
 
 #include <array>
-#include "common/bit_util.h"
+#include <bit>
 #include "video_core/command_classes/codecs/h264.h"
 #include "video_core/gpu.h"
 #include "video_core/memory_manager.h"
@@ -266,7 +266,7 @@ void H264BitWriter::WriteExpGolombCodedInt(s32 value) {
 }
 
 void H264BitWriter::WriteExpGolombCodedUInt(u32 value) {
-    const s32 size = 32 - Common::CountLeadingZeroes32(static_cast<s32>(value + 1));
+    const s32 size = 32 - std::countl_zero(value + 1);
     WriteBits(1, size);
 
     value -= (1U << (size - 1)) - 1;