From 4d49215f89cd6f23bb7676aafe0086503803b7ce Mon Sep 17 00:00:00 2001 From: winscripter <142818255+winscripter@users.noreply.github.com> Date: Wed, 9 Sep 2026 21:59:28 +0400 Subject: [PATCH] Add SimdUtils.Lzcnt --- src/ImageSharp/Common/Helpers/SimdUtils.cs | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 3e0abcd6ef..fb6f2a74d6 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; @@ -108,6 +109,40 @@ internal static partial class SimdUtils } } + /// + /// Finds the leading zero count on each item of the vector. + /// + /// The vector to compute leading zero count for. + /// Input vector with leading zero count on each element. + internal static Vector Lzcnt(Vector vector) + { + if (Avx512CD.IsSupported) + { + Vector512 v512 = vector.AsVector512(); + Vector512 lzcnt = Avx512CD.LeadingZeroCount(v512); + return lzcnt.AsVector(); + } + else if (AdvSimd.IsSupported) + { + Vector128 v128 = vector.AsVector128(); + Vector128 lzcnt = AdvSimd.LeadingZeroCount(v128); + return lzcnt.AsVector(); + } + else + { + Span data = stackalloc int[Vector.Count]; + ref int dataPtr = ref MemoryMarshal.GetReference(data); + vector.StoreUnsafe(ref dataPtr); + + for (int i = 0; i < data.Length; i++) + { + Unsafe.Add(ref dataPtr, i) = BitOperations.LeadingZeroCount((nuint)Unsafe.Add(ref dataPtr, i)); + } + + return Vector.LoadUnsafe(ref dataPtr); + } + } + [Conditional("DEBUG")] private static void DebugVerifySpanInput(ReadOnlySpan source, ReadOnlySpan dest, int shouldBeDivisibleBy) {