using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Numerics;
+using System.Runtime.Intrinsics.X86;
using Internal.Runtime.CompilerServices;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateFirstFoundByte(ulong match)
{
- // Flag least significant power of two bit
- var powerOfTwoFlag = match ^ (match - 1);
- // Shift all powers of two into the high byte and extract
- return (int)((powerOfTwoFlag * XorPowerOfTwoToHighByte) >> 57);
+ // TODO: Arm variants
+ if (Bmi1.X64.IsSupported)
+ {
+ return (int)(Bmi1.X64.TrailingZeroCount(match) >> 3);
+ }
+ else
+ {
+ // Flag least significant power of two bit
+ var powerOfTwoFlag = match ^ (match - 1);
+ // Shift all powers of two into the high byte and extract
+ return (int)((powerOfTwoFlag * XorPowerOfTwoToHighByte) >> 57);
+ }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateLastFoundByte(ulong match)
{
- // Find the most significant byte that has its highest bit set
- int index = 7;
- while ((long)match > 0)
+ // TODO: Arm variants
+ if (Lzcnt.X64.IsSupported)
{
- match = match << 8;
- index--;
+ return 7 - (int)(Lzcnt.X64.LeadingZeroCount(match) >> 3);
+ }
+ else
+ {
+ // Find the most significant byte that has its highest bit set
+ int index = 7;
+ while ((long)match > 0)
+ {
+ match = match << 8;
+ index--;
+ }
+ return index;
}
- return index;
}
private const ulong XorPowerOfTwoToHighByte = (0x07ul |
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Numerics;
+using System.Runtime.Intrinsics.X86;
-#if !netstandard
using Internal.Runtime.CompilerServices;
-#endif
#if BIT64
using nuint = System.UInt64;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateFirstFoundChar(ulong match)
{
- unchecked
+ // TODO: Arm variants
+ if (Bmi1.X64.IsSupported)
+ {
+ return (int)(Bmi1.X64.TrailingZeroCount(match) >> 4);
+ }
+ else
{
- // Flag least significant power of two bit
- var powerOfTwoFlag = match ^ (match - 1);
- // Shift all powers of two into the high byte and extract
- return (int)((powerOfTwoFlag * XorPowerOfTwoToHighChar) >> 49);
+ unchecked
+ {
+ // Flag least significant power of two bit
+ var powerOfTwoFlag = match ^ (match - 1);
+ // Shift all powers of two into the high byte and extract
+ return (int)((powerOfTwoFlag * XorPowerOfTwoToHighChar) >> 49);
+ }
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateLastFoundChar(ulong match)
{
- // Find the most significant char that has its highest bit set
- int index = 3;
- while ((long)match > 0)
+ // TODO: Arm variants
+ if (Lzcnt.X64.IsSupported)
{
- match = match << 16;
- index--;
+ return 3 - (int)(Lzcnt.X64.LeadingZeroCount(match) >> 4);
+ }
+ else
+ {
+ // Find the most significant char that has its highest bit set
+ int index = 3;
+ while ((long)match > 0)
+ {
+ match = match << 16;
+ index--;
+ }
+ return index;
}
- return index;
}
}
}