Skip to content

Commit

Permalink
make CRC32/SHA1 hashers not die when on a non-x86_64 platform
Browse files Browse the repository at this point in the history
  • Loading branch information
CasualPokePlayer committed Oct 23, 2023
1 parent 12a63e2 commit cd4e58e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
36 changes: 34 additions & 2 deletions src/BizHawk.Common/checksums/CRC32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,32 @@ public sealed class CRC32

private static readonly uint[] COMBINER_INIT_STATE;

private static readonly uint[]? CRC32Table;

static CRC32()
{
// for Add (CRC32 computation):
_calcCRC = Marshal.GetDelegateForFunctionPointer<LibBizHash.CalcCRC>(LibBizHash.BizCalcCrcFunc());
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
{
_calcCRC = Marshal.GetDelegateForFunctionPointer<LibBizHash.CalcCRC>(LibBizHash.BizCalcCrcFunc());
}
else
{
CRC32Table = new uint[256];
for (var i = 0U; i < 256U; i++)
{
var crc = i;
for (var j = 0; j < 8; j++)
{
var xor = (crc & 1U) == 1U;
crc >>= 1;
if (xor) crc ^= POLYNOMIAL_CONST;
}
CRC32Table[i] = crc;
}

_calcCRC = CrcFuncAnyCpu;
}

// for Incorporate:
var combinerState = (COMBINER_INIT_STATE = new uint[64]).AsSpan();
Expand All @@ -43,6 +65,16 @@ public static uint Calculate(ReadOnlySpan<byte> data)
return crc32.Result;
}

public static unsafe uint CrcFuncAnyCpu(uint current, IntPtr buffer, int len)
{
for (var i = 0; i < len; i++)
{
current = CRC32Table[(current ^ ((byte*)buffer)[i]) & 0xFF] ^ (current >> 8);
}

return current;
}

private static void gf2_matrix_square(Span<uint> square, ReadOnlySpan<uint> mat)
{
if (mat.Length != square.Length) throw new ArgumentException(message: "must be same length as " + nameof(square), paramName: nameof(mat));
Expand Down Expand Up @@ -76,7 +108,7 @@ public uint Current

public unsafe void Add(ReadOnlySpan<byte> data)
{
fixed (byte* d = &data.GetPinnableReference())
fixed (byte* d = data)
{
_current = _calcCRC(_current, (IntPtr) d, data.Length);
}
Expand Down
6 changes: 4 additions & 2 deletions src/BizHawk.Common/checksums/SHA1Checksum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,16 @@ private static SHA1 SHA1Impl
}
}

private static readonly bool UseUnmanagedImpl = RuntimeInformation.ProcessArchitecture == Architecture.X64 && LibBizHash.BizSupportsShaInstructions();

public static byte[] Compute(byte[] data)
=> LibBizHash.BizSupportsShaInstructions()
=> UseUnmanagedImpl
? UnmanagedImpl(data)
: SHA1Impl.ComputeHash(data);

public static byte[] ComputeConcat(byte[] dataA, byte[] dataB)
{
if (LibBizHash.BizSupportsShaInstructions()) return UnmanagedImpl(dataA.ConcatArray(dataB));
if (UseUnmanagedImpl) return UnmanagedImpl(dataA.ConcatArray(dataB));
using var impl = IncrementalHash.CreateHash(HashAlgorithmName.SHA1);
impl.AppendData(dataA);
impl.AppendData(dataB);
Expand Down

0 comments on commit cd4e58e

Please sign in to comment.