using System; using System.Runtime.InteropServices; namespace ARMeilleure.Instructions { static partial class SoftFallback { [UnmanagedCallersOnly] public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). { value ^= value >> 1; int highBit = size - 2; for (int bit = highBit; bit >= 0; bit--) { if (((int)(value >> bit) & 0b1) != 0) { return (ulong)(highBit - bit); } } return (ulong)(size - 1); } private static ReadOnlySpan ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]; [UnmanagedCallersOnly] public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). { if (value == 0ul) { return (ulong)size; } int nibbleIdx = size; int preCount, count = 0; do { nibbleIdx -= 4; preCount = ClzNibbleTbl[(int)(value >> nibbleIdx) & 0b1111]; count += preCount; } while (preCount == 4); return (ulong)count; } } }