diff --git a/Ryujinx.Common/Utilities/BitUtils.cs b/Ryujinx.Common/Utilities/BitUtils.cs index 180f10632..b231886f9 100644 --- a/Ryujinx.Common/Utilities/BitUtils.cs +++ b/Ryujinx.Common/Utilities/BitUtils.cs @@ -1,11 +1,10 @@ using System; +using System.Numerics; namespace Ryujinx.Common { public static class BitUtils { - private static ReadOnlySpan ClzNibbleTbl => new byte[] { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; - public static uint AlignUp(uint value, int size) { return (uint)AlignUp((int)value, size); @@ -76,60 +75,7 @@ namespace Ryujinx.Common public static int Pow2RoundDown(int value) { - return IsPowerOfTwo32(value) ? value : Pow2RoundUp(value) >> 1; - } - - public static bool IsPowerOfTwo32(int value) - { - return value != 0 && (value & (value - 1)) == 0; - } - - public static bool IsPowerOfTwo64(long value) - { - return value != 0 && (value & (value - 1)) == 0; - } - - public static int CountLeadingZeros32(int value) - { - return (int)CountLeadingZeros((ulong)value, 32); - } - - public static int CountLeadingZeros64(long value) - { - return (int)CountLeadingZeros((ulong)value, 64); - } - - private static ulong CountLeadingZeros(ulong value, int size) - { - 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; - } - - public static int CountTrailingZeros32(int value) - { - int count = 0; - - while (((value >> count) & 1) == 0) - { - count++; - } - - return count; + return BitOperations.IsPow2(value) ? value : Pow2RoundUp(value) >> 1; } public static long ReverseBits64(long value) diff --git a/Ryujinx.Graphics.Texture/BlockLinearLayout.cs b/Ryujinx.Graphics.Texture/BlockLinearLayout.cs index 02b699872..e098e959c 100644 --- a/Ryujinx.Graphics.Texture/BlockLinearLayout.cs +++ b/Ryujinx.Graphics.Texture/BlockLinearLayout.cs @@ -1,4 +1,5 @@ using Ryujinx.Common; +using System.Numerics; using System.Runtime.CompilerServices; using static Ryujinx.Graphics.Texture.BlockLinearConstants; @@ -47,15 +48,15 @@ namespace Ryujinx.Graphics.Texture { _texBpp = bpp; - _bppShift = BitUtils.CountTrailingZeros32(bpp); + _bppShift = BitOperations.TrailingZeroCount(bpp); _bhMask = gobBlocksInY - 1; _bdMask = gobBlocksInZ - 1; - _bhShift = BitUtils.CountTrailingZeros32(gobBlocksInY); - _bdShift = BitUtils.CountTrailingZeros32(gobBlocksInZ); + _bhShift = BitOperations.TrailingZeroCount(gobBlocksInY); + _bdShift = BitOperations.TrailingZeroCount(gobBlocksInZ); - _xShift = BitUtils.CountTrailingZeros32(GobSize * gobBlocksInY * gobBlocksInZ); + _xShift = BitOperations.TrailingZeroCount(GobSize * gobBlocksInY * gobBlocksInZ); RobAndSliceSizes rsSizes = GetRobAndSliceSizes(width, height, gobBlocksInY, gobBlocksInZ); diff --git a/Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs b/Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs index 7f767c1c4..8b4c2dda4 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/MersenneTwister.cs @@ -1,4 +1,5 @@ using Ryujinx.Common; +using System.Numerics; namespace Ryujinx.HLE.HOS.Kernel.Common { @@ -41,10 +42,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Common range++; // This is log2(Range) plus one. - int nextRangeLog2 = 64 - BitUtils.CountLeadingZeros64(range); + int nextRangeLog2 = 64 - BitOperations.LeadingZeroCount((ulong)range); // If Range is already power of 2, subtract one to use log2(Range) directly. - int rangeLog2 = nextRangeLog2 - (BitUtils.IsPowerOfTwo64(range) ? 1 : 0); + int rangeLog2 = nextRangeLog2 - (BitOperations.IsPow2(range) ? 1 : 0); int parts = rangeLog2 > 32 ? 2 : 1; int bitsPerPart = rangeLog2 / parts; diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs index f35a3c363..43e3e820b 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryRegionManager.cs @@ -1,6 +1,7 @@ using Ryujinx.Common; using Ryujinx.HLE.HOS.Kernel.Common; using System.Diagnostics; +using System.Numerics; namespace Ryujinx.HLE.HOS.Kernel.Memory { @@ -259,11 +260,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory if (backwards) { - index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask); + index = (index * 64 + 63) - BitOperations.LeadingZeroCount((ulong)mask); } else { - index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask)); + index = index * 64 + BitOperations.LeadingZeroCount((ulong)BitUtils.ReverseBits64(mask)); } } @@ -312,11 +313,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory if (backwards) { - index = index * 64 + BitUtils.CountLeadingZeros64(BitUtils.ReverseBits64(mask)); + index = index * 64 + BitOperations.LeadingZeroCount((ulong)BitUtils.ReverseBits64(mask)); } else { - index = (index * 64 + 63) - BitUtils.CountLeadingZeros64(mask); + index = (index * 64 + 63) - BitOperations.LeadingZeroCount((ulong)mask); } } diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs b/Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs index 0392b9304..ed57ae047 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/KContextIdManager.cs @@ -1,5 +1,6 @@ using Ryujinx.Common; using System; +using System.Numerics; namespace Ryujinx.HLE.HOS.Kernel.Process { @@ -32,7 +33,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process { int mask = _idMasks[index]; - int firstFreeBit = BitUtils.CountLeadingZeros32((mask + 1) & ~mask); + int firstFreeBit = BitOperations.LeadingZeroCount((uint)((mask + 1) & ~mask)); if (firstFreeBit < 32) { diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs index 55e839ab0..7fb98017c 100644 --- a/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs +++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs @@ -3,6 +3,7 @@ using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Threading; using System; +using System.Numerics; namespace Ryujinx.HLE.HOS.Kernel.Process { @@ -130,7 +131,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return KernelResult.Success; } - int codeMask = 1 << (32 - BitUtils.CountLeadingZeros32(code + 1)); + int codeMask = 1 << (32 - BitOperations.LeadingZeroCount((uint)code + 1)); // Check if the property was already set. if (((mask0 & codeMask) & 0x1e008) != 0)