Editor/HumanoidRetargeter/Embedded/ZstdSharp/Unsafe/ZstdInternal.cs
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using static HumanoidRetargeterZstd.UnsafeHelper;
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics.Arm;
namespace HumanoidRetargeterZstd.Unsafe
{
public static unsafe partial class Methods
{
private static ReadOnlySpan<uint> Span_repStartValue => new uint[3]
{
1,
4,
8
};
private static uint* repStartValue => (uint*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref MemoryMarshal.GetReference(Span_repStartValue));
private static readonly nuint* ZSTD_fcs_fieldSize = GetArrayPointer(new nuint[4] { 0, 2, 4, 8 });
private static readonly nuint* ZSTD_did_fieldSize = GetArrayPointer(new nuint[4] { 0, 1, 2, 4 });
private const uint ZSTD_blockHeaderSize = 3;
private static ReadOnlySpan<byte> Span_LL_bits => new byte[36]
{
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2,
3,
3,
4,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
};
private static byte* LL_bits => (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref MemoryMarshal.GetReference(Span_LL_bits));
private static ReadOnlySpan<byte> Span_ML_bits => new byte[53]
{
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2,
3,
3,
4,
4,
5,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
};
private static byte* ML_bits => (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref MemoryMarshal.GetReference(Span_ML_bits));
/*-*******************************************
* Shared functions to include for inlining
*********************************************/
private static void ZSTD_copy8(void* dst, void* src)
{
memcpy(dst, src, 8);
}
/* Need to use memmove here since the literal buffer can now be located within
the dst buffer. In circumstances where the op "catches up" to where the
literal buffer is, there can be partial overlaps in this call on the final
copy if the literal is being shifted by less than 16 bytes. */
private static void ZSTD_copy16(void* dst, void* src)
{
if (AdvSimd.IsSupported)
{
AdvSimd.Store((byte*)dst, AdvSimd.LoadVector128((byte*)src));
}
else
if (Sse2.IsSupported)
{
Sse2.Store((byte*)dst, Sse2.LoadVector128((byte*)src));
}
else
{
var v1 = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<ulong>((ulong*)src);
var v2 = System.Runtime.CompilerServices.Unsafe.ReadUnaligned<ulong>((ulong*)src + 1);
System.Runtime.CompilerServices.Unsafe.WriteUnaligned((ulong*)dst, v1);
System.Runtime.CompilerServices.Unsafe.WriteUnaligned((ulong*)dst + 1, v2);
}
}
/*! ZSTD_wildcopy() :
* Custom version of ZSTD_memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
* @param ovtype controls the overlap detection
* - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
* - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
* The src buffer must be before the dst buffer.
*/
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ZSTD_wildcopy(void* dst, void* src, nint length, ZSTD_overlap_e ovtype)
{
nint diff = (nint)((byte*)dst - (byte*)src);
byte* ip = (byte*)src;
byte* op = (byte*)dst;
byte* oend = op + length;
if (ovtype == ZSTD_overlap_e.ZSTD_overlap_src_before_dst && diff < 16)
{
do
{
ZSTD_copy8(op, ip);
op += 8;
ip += 8;
}
while (op < oend);
}
else
{
assert(diff >= 16 || diff <= -16);
ZSTD_copy16(op, ip);
if (16 >= length)
return;
op += 16;
ip += 16;
do
{
{
ZSTD_copy16(op, ip);
op += 16;
ip += 16;
}
{
ZSTD_copy16(op, ip);
op += 16;
ip += 16;
}
}
while (op < oend);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static nuint ZSTD_limitCopy(void* dst, nuint dstCapacity, void* src, nuint srcSize)
{
nuint length = dstCapacity < srcSize ? dstCapacity : srcSize;
if (length > 0)
{
memcpy(dst, src, (uint)length);
}
return length;
}
}
}