diff --git a/ChocolArm64/Instruction/ASoftFallback.cs b/ChocolArm64/Instruction/ASoftFallback.cs index 48b57dad12..7f69f4723c 100644 --- a/ChocolArm64/Instruction/ASoftFallback.cs +++ b/ChocolArm64/Instruction/ASoftFallback.cs @@ -12,21 +12,44 @@ namespace ChocolArm64.Instruction public static ulong CountLeadingSigns(ulong Value, int Size) { - return CountLeadingZeros((Value >> 1) ^ Value, Size - 1); + Value ^= Value >> 1; + + Value <<= 64 - Size + 1; + Value = HighZeros(Value, Size); + Value >>= 64 - Size + 1; + + return CountSetBits64(Value, Size); } public static ulong CountLeadingZeros(ulong Value, int Size) { - Value <<= 64 - Size; + Value = HighZeros(Value, Size); + return CountSetBits64(Value, Size); + } + + private static ulong HighZeros(ulong Value, int Size) + { Value |= Value >> 1; Value |= Value >> 2; Value |= Value >> 4; - if (Size >= 15) Value |= Value >> 8 ; - if (Size >= 31) Value |= Value >> 16; - if (Size >= 63) Value |= Value >> 32; + if (Size >= 16) Value |= Value >> 8 ; + if (Size >= 32) Value |= Value >> 16; + if (Size == 64) Value |= Value >> 32; - return CountSetBits64(~Value >> (64 - Size), Size); + return ~Value; + } + + private static ulong CountSetBits64(ulong Value, int Size) + { + Value = ((Value >> 1) & 0x5555555555555555) + (Value & 0x5555555555555555); + Value = ((Value >> 2) & 0x3333333333333333) + (Value & 0x3333333333333333); + Value = ((Value >> 4) + Value) & 0x0f0f0f0f0f0f0f0f; + if (Size >= 16) Value += Value >> 8 ; + if (Size >= 32) Value += Value >> 16; + if (Size == 64) Value += Value >> 32; + + return Value & 0xff; } public static uint CountSetBits8(uint Value) @@ -37,18 +60,6 @@ namespace ChocolArm64.Instruction return (Value >> 4) + (Value & 0x0f); } - private static ulong CountSetBits64(ulong Value, int Size) - { - Value = ((Value >> 1 ) & 0x5555555555555555) + (Value & 0x5555555555555555); - Value = ((Value >> 2 ) & 0x3333333333333333) + (Value & 0x3333333333333333); - Value = ((Value >> 4 ) + Value) & 0x0f0f0f0f0f0f0f0f; - if (Size >= 15) Value += Value >> 8 ; - if (Size >= 31) Value += Value >> 16; - if (Size >= 63) Value += Value >> 32; - - return Value & 0xff; - } - private const uint Crc32RevPoly = 0xedb88320; private const uint Crc32cRevPoly = 0x82f63b78;