mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-12 22:36:59 +00:00
50 lines
1.3 KiB
C#
50 lines
1.3 KiB
C#
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<byte> 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;
|
|
}
|
|
}
|
|
}
|