From 15eb68f1d0c251ea80a97fed3bbdc2237fa15268 Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Sat, 13 Oct 2018 01:10:05 +0200 Subject: [PATCH] Update ASoftFallback.cs --- ChocolArm64/Instruction/ASoftFallback.cs | 59 ++++++++++++++++-------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/ChocolArm64/Instruction/ASoftFallback.cs b/ChocolArm64/Instruction/ASoftFallback.cs index a7bc108591..c356048923 100644 --- a/ChocolArm64/Instruction/ASoftFallback.cs +++ b/ChocolArm64/Instruction/ASoftFallback.cs @@ -386,7 +386,7 @@ namespace ChocolArm64.Instruction #endregion #region "Count" - public static ulong CountLeadingSigns(ulong Value, int Size) + public static ulong CountLeadingSigns(ulong Value, int Size) // Size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). { Value ^= Value >> 1; @@ -405,33 +405,54 @@ namespace ChocolArm64.Instruction private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; - public static ulong CountLeadingZeros(ulong Value, int Size) + public static ulong CountLeadingZeros(ulong Value, int Size) // Size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). { - if (Value == 0) + if (Lzcnt.IsSupported && Size >= 32) { - return (ulong)Size; + return Size == 32 + ? (ulong)Lzcnt.LeadingZeroCount((uint)Value) + : Lzcnt.LeadingZeroCount(Value); } - - int NibbleIdx = Size; - int PreCount, Count = 0; - - do + else { - NibbleIdx -= 4; - PreCount = ClzNibbleTbl[(Value >> NibbleIdx) & 0b1111]; - Count += PreCount; - } - while (PreCount == 4); + if (Value == 0ul) + { + return (ulong)Size; + } - return (ulong)Count; + int NibbleIdx = Size; + int PreCount, Count = 0; + + do + { + NibbleIdx -= 4; + PreCount = ClzNibbleTbl[(Value >> NibbleIdx) & 0b1111]; + Count += PreCount; + } + while (PreCount == 4); + + return (ulong)Count; + } } - public static uint CountSetBits8(uint Value) + public static ulong CountSetBits8(ulong Value) // "Size" is 8 (SIMD&FP Inst.). { - Value = ((Value >> 1) & 0x55) + (Value & 0x55); - Value = ((Value >> 2) & 0x33) + (Value & 0x33); + if (Popcnt.IsSupported) + { + return (ulong)Popcnt.PopCount(Value); + } + else + { + if (Value == 0xfful) + { + return 8ul; + } - return (Value >> 4) + (Value & 0x0f); + Value = ((Value >> 1) & 0x55ul) + (Value & 0x55ul); + Value = ((Value >> 2) & 0x33ul) + (Value & 0x33ul); + + return (Value >> 4) + (Value & 0x0ful); + } } #endregion