This commit is contained in:
Aigio Liu
2022-07-27 12:53:30 +08:00
parent 3afd331ced
commit 1a2b0e5fbc
7 changed files with 481 additions and 481 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ static class Convert
#if NET5_0_OR_GREATER
var result = GC.AllocateUninitializedArray<byte>(resultLength);
#else
var result = new byte[resultLength];
var result = new byte[resultLength];
#endif
fixed (byte* outPtr = result)
{
+61 -61
View File
@@ -1,76 +1,76 @@
//using System.Diagnostics;
//#if NETCOREAPP3_0_OR_GREATER
//using System.Numerics;
//using System.Runtime.Intrinsics;
//using System.Runtime.Intrinsics.X86;
//#endif
using System.Diagnostics;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
//namespace HexMate;
namespace HexMate;
//internal static unsafe class CharHelper
//{
// internal static int CountUsefulCharacters(char* inputPtr, int inputLength)
// {
// Debug.Assert(inputLength > 0);
internal static unsafe class CharHelper
{
internal static int CountUsefulCharacters(char* inputPtr, int inputLength)
{
Debug.Assert(inputLength > 0);
// // All characters above ' ' (space) are considered useful, as it is good enough, if this method
// // returns an upper bound on the number of bytes encoded in the given input.
// var byteLength = inputLength * 2;
// var usefulCharacters = 0;
//#if NETCOREAPP3_0_OR_GREATER
// var byteSrc = (byte*)inputPtr;
// All characters above ' ' (space) are considered useful, as it is good enough, if this method
// returns an upper bound on the number of bytes encoded in the given input.
var byteLength = inputLength * 2;
var usefulCharacters = 0;
#if NETCOREAPP3_0_OR_GREATER
var byteSrc = (byte*)inputPtr;
// if (Avx2.IsSupported && byteLength >= 32)
// {
// var space = Vector256.Create(' ').AsInt16();
// var bytesToProcess = FastMath.RoundDownTo32(byteLength);
// var end = byteSrc + bytesToProcess;
// while (byteSrc != end)
// {
// var input = Avx.LoadVector256(byteSrc).AsInt16();
if (Avx2.IsSupported && byteLength >= 32)
{
var space = Vector256.Create(' ').AsInt16();
var bytesToProcess = FastMath.RoundDownTo32(byteLength);
var end = byteSrc + bytesToProcess;
while (byteSrc != end)
{
var input = Avx.LoadVector256(byteSrc).AsInt16();
// var cnt = Avx2.CompareGreaterThan(input, space);
// var mask = (uint)Avx2.MoveMask(cnt.AsByte());
// usefulCharacters += BitOperations.PopCount(mask) >> 1;
var cnt = Avx2.CompareGreaterThan(input, space);
var mask = (uint)Avx2.MoveMask(cnt.AsByte());
usefulCharacters += BitOperations.PopCount(mask) >> 1;
// byteSrc += 32;
// }
byteSrc += 32;
}
// byteLength -= bytesToProcess;
// }
byteLength -= bytesToProcess;
}
// if (Sse2.IsSupported && byteLength >= 16)
// {
// var space = Vector128.Create(' ').AsInt16();
// var bytesToProcess = FastMath.RoundDownTo16(byteLength);
// var end = byteSrc + bytesToProcess;
// while (byteSrc != end)
// {
// var input = Sse2.LoadVector128(byteSrc).AsInt16();
if (Sse2.IsSupported && byteLength >= 16)
{
var space = Vector128.Create(' ').AsInt16();
var bytesToProcess = FastMath.RoundDownTo16(byteLength);
var end = byteSrc + bytesToProcess;
while (byteSrc != end)
{
var input = Sse2.LoadVector128(byteSrc).AsInt16();
// var cnt = Sse2.CompareGreaterThan(input, space);
// var mask = (uint)Sse2.MoveMask(cnt.AsByte());
// usefulCharacters += BitOperations.PopCount(mask) >> 1;
var cnt = Sse2.CompareGreaterThan(input, space);
var mask = (uint)Sse2.MoveMask(cnt.AsByte());
usefulCharacters += BitOperations.PopCount(mask) >> 1;
// byteSrc += 16;
// }
byteSrc += 16;
}
// byteLength -= bytesToProcess;
// }
byteLength -= bytesToProcess;
}
// inputPtr = (char*)byteSrc;
//#endif
// const uint intSpace = ' ';
inputPtr = (char*)byteSrc;
#endif
const uint intSpace = ' ';
// var charEnd = inputPtr + (byteLength / 2);
// while (inputPtr < charEnd)
// {
// uint c = *inputPtr++;
var charEnd = inputPtr + (byteLength / 2);
while (inputPtr < charEnd)
{
uint c = *inputPtr++;
// if (c > intSpace)
// usefulCharacters++;
// }
if (c > intSpace)
usefulCharacters++;
}
// return usefulCharacters;
// }
//}
return usefulCharacters;
}
}
@@ -1,130 +1,130 @@
//#if NETCOREAPP3_0_OR_GREATER
#if NETCOREAPP3_0_OR_GREATER
//using System.Diagnostics;
//using System.Runtime.CompilerServices;
//using System.Runtime.Intrinsics;
//using static HexMate.VectorConstants;
//using static HexMate.VectorUtils;
//using static System.Runtime.Intrinsics.X86.Avx;
//using static System.Runtime.Intrinsics.X86.Avx2;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using static HexMate.VectorConstants;
using static HexMate.VectorUtils;
using static System.Runtime.Intrinsics.X86.Avx;
using static System.Runtime.Intrinsics.X86.Avx2;
//namespace HexMate;
namespace HexMate;
//internal static partial class Utf16HexParser
//{
// internal static unsafe class Avx2
// {
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal static bool TryParse(ref char* srcBytes, ref byte* destBytes, int destLength)
// {
// Debug.Assert(System.Runtime.Intrinsics.X86.Avx2.IsSupported);
internal static partial class Utf16HexParser
{
internal static unsafe class Avx2
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TryParse(ref char* srcBytes, ref byte* destBytes, int destLength)
{
Debug.Assert(System.Runtime.Intrinsics.X86.Avx2.IsSupported);
// var x0F = Vector256.Create((byte)0x0F);
// var xF0 = Vector256.Create((byte)0xF0);
// var digHexSelector = ReadVector256(s_upperLowerDigHexSelector);
// var digits = ReadVector256(s_digits);
// var hexs = ReadVector256(s_hexs);
// var evenBytes = ReadVector256(s_evenBytes);
// var oddBytes = ReadVector256(s_oddBytes);
// var src = (byte*)srcBytes;
// var dest = destBytes;
var x0F = Vector256.Create((byte)0x0F);
var xF0 = Vector256.Create((byte)0xF0);
var digHexSelector = ReadVector256(s_upperLowerDigHexSelector);
var digits = ReadVector256(s_digits);
var hexs = ReadVector256(s_hexs);
var evenBytes = ReadVector256(s_evenBytes);
var oddBytes = ReadVector256(s_oddBytes);
var src = (byte*)srcBytes;
var dest = destBytes;
// var target = dest + FastMath.RoundDownTo32(destLength);
// int leftOk, rightOk;
// while (dest != target)
// {
// var a = LoadVector256(src).AsInt16();
// src += 32;
// var b = LoadVector256(src).AsInt16();
// src += 32;
// var c = LoadVector256(src).AsInt16();
// src += 32;
// var d = LoadVector256(src).AsInt16();
// src += 32;
var target = dest + FastMath.RoundDownTo32(destLength);
int leftOk, rightOk;
while (dest != target)
{
var a = LoadVector256(src).AsInt16();
src += 32;
var b = LoadVector256(src).AsInt16();
src += 32;
var c = LoadVector256(src).AsInt16();
src += 32;
var d = LoadVector256(src).AsInt16();
src += 32;
// var ab = PackUnsignedSaturate(a, b);
// var cd = PackUnsignedSaturate(c, d);
var ab = PackUnsignedSaturate(a, b);
var cd = PackUnsignedSaturate(c, d);
// var inputLeft = Permute4x64(ab.AsUInt64(), 0b11_01_10_00).AsByte();
// var inputRight = Permute4x64(cd.AsUInt64(), 0b11_01_10_00).AsByte();
var inputLeft = Permute4x64(ab.AsUInt64(), 0b11_01_10_00).AsByte();
var inputRight = Permute4x64(cd.AsUInt64(), 0b11_01_10_00).AsByte();
// var loNibbleLeft = And(inputLeft, x0F);
// var loNibbleRight = And(inputRight, x0F);
var loNibbleLeft = And(inputLeft, x0F);
var loNibbleRight = And(inputRight, x0F);
// var hiNibbleLeft = And(inputLeft, xF0);
// var hiNibbleRight = And(inputRight, xF0);
var hiNibbleLeft = And(inputLeft, xF0);
var hiNibbleRight = And(inputRight, xF0);
// var leftDigits = Shuffle(digits, loNibbleLeft);
// var leftHex = Shuffle(hexs, loNibbleLeft);
var leftDigits = Shuffle(digits, loNibbleLeft);
var leftHex = Shuffle(hexs, loNibbleLeft);
// var hiNibbleShLeft = ShiftRightLogical(hiNibbleLeft.AsInt16(), 4).AsByte();
// var hiNibbleShRight = ShiftRightLogical(hiNibbleRight.AsInt16(), 4).AsByte();
var hiNibbleShLeft = ShiftRightLogical(hiNibbleLeft.AsInt16(), 4).AsByte();
var hiNibbleShRight = ShiftRightLogical(hiNibbleRight.AsInt16(), 4).AsByte();
// var rightDigits = Shuffle(digits, loNibbleRight);
// var rightHex = Shuffle(hexs, loNibbleRight);
var rightDigits = Shuffle(digits, loNibbleRight);
var rightHex = Shuffle(hexs, loNibbleRight);
// var magicLeft = Shuffle(digHexSelector, hiNibbleShLeft);
// var magicRight = Shuffle(digHexSelector, hiNibbleShRight);
var magicLeft = Shuffle(digHexSelector, hiNibbleShLeft);
var magicRight = Shuffle(digHexSelector, hiNibbleShRight);
// var valueLeft = BlendVariable(leftDigits, leftHex, magicLeft);
// var valueRight = BlendVariable(rightDigits, rightHex, magicRight);
var valueLeft = BlendVariable(leftDigits, leftHex, magicLeft);
var valueRight = BlendVariable(rightDigits, rightHex, magicRight);
// var errLeft = ShiftLeftLogical(magicLeft.AsInt16(), 7).AsByte();
// var errRight = ShiftLeftLogical(magicRight.AsInt16(), 7).AsByte();
var errLeft = ShiftLeftLogical(magicLeft.AsInt16(), 7).AsByte();
var errRight = ShiftLeftLogical(magicRight.AsInt16(), 7).AsByte();
// var evenBytesLeft = Shuffle(valueLeft, evenBytes);
// var oddBytesLeft = Shuffle(valueLeft, oddBytes);
// var evenBytesRight = Shuffle(valueRight, evenBytes);
// var oddBytesRight = Shuffle(valueRight, oddBytes);
var evenBytesLeft = Shuffle(valueLeft, evenBytes);
var oddBytesLeft = Shuffle(valueLeft, oddBytes);
var evenBytesRight = Shuffle(valueRight, evenBytes);
var oddBytesRight = Shuffle(valueRight, oddBytes);
// evenBytesLeft = ShiftLeftLogical(evenBytesLeft.AsUInt16(), 4).AsByte();
// evenBytesRight = ShiftLeftLogical(evenBytesRight.AsUInt16(), 4).AsByte();
evenBytesLeft = ShiftLeftLogical(evenBytesLeft.AsUInt16(), 4).AsByte();
evenBytesRight = ShiftLeftLogical(evenBytesRight.AsUInt16(), 4).AsByte();
// evenBytesLeft = Or(evenBytesLeft, oddBytesLeft);
// evenBytesRight = Or(evenBytesRight, oddBytesRight);
evenBytesLeft = Or(evenBytesLeft, oddBytesLeft);
evenBytesRight = Or(evenBytesRight, oddBytesRight);
// var result = Merge(evenBytesLeft, evenBytesRight);
var result = Merge(evenBytesLeft, evenBytesRight);
// var validationResultLeft = Or(errLeft, valueLeft);
// var validationResultRight = Or(errRight, valueRight);
var validationResultLeft = Or(errLeft, valueLeft);
var validationResultRight = Or(errRight, valueRight);
// leftOk = MoveMask(validationResultLeft);
// rightOk = MoveMask(validationResultRight);
leftOk = MoveMask(validationResultLeft);
rightOk = MoveMask(validationResultRight);
// if ((leftOk | rightOk) != 0) goto Err;
if ((leftOk | rightOk) != 0) goto Err;
// Store(dest, result);
// dest += 32;
// }
Store(dest, result);
dest += 32;
}
// srcBytes = (char*)src;
// destBytes = dest;
// return true;
srcBytes = (char*)src;
destBytes = dest;
return true;
// Err:
// if (leftOk != 0)
// {
// srcBytes = (char*)(src - 128);
// destBytes = dest;
// return false;
// }
// else
// {
// Debug.Assert(rightOk != 0);
// srcBytes = (char*)(src - 64);
// destBytes = dest;
// return false;
// }
// }
Err:
if (leftOk != 0)
{
srcBytes = (char*)(src - 128);
destBytes = dest;
return false;
}
else
{
Debug.Assert(rightOk != 0);
srcBytes = (char*)(src - 64);
destBytes = dest;
return false;
}
}
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// private static Vector256<byte> Merge(Vector256<byte> a, Vector256<byte> b)
// {
// var a1 = Permute4x64(a.AsUInt64(), 0b11_10_10_00);
// var b1 = Permute4x64(b.AsUInt64(), 0b11_00_01_00);
// return Blend(a1.AsUInt32(), b1.AsUInt32(), 0b1111_0000).AsByte();
// }
// }
//}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector256<byte> Merge(Vector256<byte> a, Vector256<byte> b)
{
var a1 = Permute4x64(a.AsUInt64(), 0b11_10_10_00);
var b1 = Permute4x64(b.AsUInt64(), 0b11_00_01_00);
return Blend(a1.AsUInt32(), b1.AsUInt32(), 0b1111_0000).AsByte();
}
}
}
//#endif
#endif
@@ -1,60 +1,60 @@
//using System.Runtime.CompilerServices;
//using static HexMate.ScalarConstants;
using System.Runtime.CompilerServices;
using static HexMate.ScalarConstants;
//namespace HexMate;
namespace HexMate;
//internal static partial class Utf16HexParser
//{
// internal static unsafe class Fixed
// {
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal static bool TryParse(ref char* srcBytes, int srcLength, ref byte* destBytes, int destLength)
// {
// var src = srcBytes;
// var dest = destBytes;
internal static partial class Utf16HexParser
{
internal static unsafe class Fixed
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TryParse(ref char* srcBytes, int srcLength, ref byte* destBytes, int destLength)
{
var src = srcBytes;
var dest = destBytes;
// var srcTarget = src + srcLength;
// var destTarget = dest + destLength;
var srcTarget = src + srcLength;
var destTarget = dest + destLength;
// fixed (byte* lut = LookupUpperLower)
// {
// int hi, lo;
// while (srcTarget > src && destTarget > dest)
// {
// ReadHi:
// int valHi = *src++;
// if (valHi > 0xFF) { goto Err; }
// hi = lut[valHi];
// if (hi >= 0xFE)
// {
// if (hi == 0xFF) goto Err;
// if (srcTarget > src) goto ReadHi; // skip whitespace
// }
// *dest |= (byte)(hi << 4);
fixed (byte* lut = LookupUpperLower)
{
int hi, lo;
while (srcTarget > src && destTarget > dest)
{
ReadHi:
int valHi = *src++;
if (valHi > 0xFF) { goto Err; }
hi = lut[valHi];
if (hi >= 0xFE)
{
if (hi == 0xFF) goto Err;
if (srcTarget > src) goto ReadHi; // skip whitespace
}
*dest |= (byte)(hi << 4);
// ReadLo:
// int valLo = *src++;
// if (valLo > 0xFF) goto Err;
// lo = lut[valLo];
// if (lo >= 0xFE)
// {
// if (lo == 0xFF) goto Err;
// if (srcTarget > src) goto ReadLo; // skip whitespace
// }
// *dest |= (byte)lo;
ReadLo:
int valLo = *src++;
if (valLo > 0xFF) goto Err;
lo = lut[valLo];
if (lo >= 0xFE)
{
if (lo == 0xFF) goto Err;
if (srcTarget > src) goto ReadLo; // skip whitespace
}
*dest |= (byte)lo;
// dest++;
// }
// }
dest++;
}
}
// srcBytes = src;
// destBytes = dest;
// return true;
srcBytes = src;
destBytes = dest;
return true;
// Err:
// srcBytes = src - 1;
// destBytes = dest;
// return false;
// }
// }
//}
Err:
srcBytes = src - 1;
destBytes = dest;
return false;
}
}
}
@@ -1,61 +1,61 @@
//#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
//using System.Runtime.CompilerServices;
//using static HexMate.ScalarConstants;
using System.Runtime.CompilerServices;
using static HexMate.ScalarConstants;
//namespace HexMate;
namespace HexMate;
//internal static partial class Utf16HexParser
//{
// internal static unsafe class Span
// {
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal static bool TryParse(ref char* srcBytes, int srcLength, ref byte* destBytes, int destLength)
// {
// var src = srcBytes;
// var dest = destBytes;
internal static partial class Utf16HexParser
{
internal static unsafe class Span
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TryParse(ref char* srcBytes, int srcLength, ref byte* destBytes, int destLength)
{
var src = srcBytes;
var dest = destBytes;
// var srcTarget = src + srcLength;
// var destTarget = dest + destLength;
var srcTarget = src + srcLength;
var destTarget = dest + destLength;
// int hi, lo;
// while (srcTarget > src && destTarget > dest)
// {
// ReadHi:
// int valHi = *src++;
// if (valHi > 0xFF) { goto Err; }
// hi = LookupUpperLower[valHi];
// if (hi >= 0xFE)
// {
// if (hi == 0xFF) goto Err;
// if (srcTarget > src) goto ReadHi;
// }
// *dest |= (byte)(hi << 4);
int hi, lo;
while (srcTarget > src && destTarget > dest)
{
ReadHi:
int valHi = *src++;
if (valHi > 0xFF) { goto Err; }
hi = LookupUpperLower[valHi];
if (hi >= 0xFE)
{
if (hi == 0xFF) goto Err;
if (srcTarget > src) goto ReadHi;
}
*dest |= (byte)(hi << 4);
// ReadLo:
// int valLo = *src++;
// if (valLo > 0xFF) goto Err;
// lo = LookupUpperLower[valLo];
// if (lo >= 0xFE)
// {
// if (lo == 0xFF) goto Err;
// if (srcTarget > src) goto ReadLo;
// }
// *dest |= (byte)lo;
ReadLo:
int valLo = *src++;
if (valLo > 0xFF) goto Err;
lo = LookupUpperLower[valLo];
if (lo >= 0xFE)
{
if (lo == 0xFF) goto Err;
if (srcTarget > src) goto ReadLo;
}
*dest |= (byte)lo;
// dest++;
// }
dest++;
}
// srcBytes = src;
// destBytes = dest;
// return true;
srcBytes = src;
destBytes = dest;
return true;
// Err:
// srcBytes = src - 1;
// destBytes = dest;
// return false;
// }
// }
//}
Err:
srcBytes = src - 1;
destBytes = dest;
return false;
}
}
}
//#endif
#endif
@@ -1,142 +1,142 @@
//#if NETCOREAPP3_0_OR_GREATER
#if NETCOREAPP3_0_OR_GREATER
//using System.Diagnostics;
//using System.Runtime.CompilerServices;
//using System.Runtime.Intrinsics;
//using static System.Runtime.Intrinsics.X86.Sse2;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using static System.Runtime.Intrinsics.X86.Sse2;
//namespace HexMate;
namespace HexMate;
//internal static partial class Utf16HexParser
//{
// internal static unsafe class Sse2
// {
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal static bool TryParse(ref char* srcBytes, ref byte* destBytes, int destLength)
// {
// Debug.Assert(System.Runtime.Intrinsics.X86.Sse2.IsSupported);
internal static partial class Utf16HexParser
{
internal static unsafe class Sse2
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TryParse(ref char* srcBytes, ref byte* destBytes, int destLength)
{
Debug.Assert(System.Runtime.Intrinsics.X86.Sse2.IsSupported);
// var x05 = Vector128.Create((byte)0x05);
// var x09 = Vector128.Create((byte)0x09);
// var x0A = Vector128.Create((byte)0x0A);
// var x20 = Vector128.Create((byte)0x20);
// var x30 = Vector128.Create((byte)0x30);
// var x40 = Vector128.Create((byte)0x40);
// var x41 = Vector128.Create((byte)0x41);
// var x60 = Vector128.Create((byte)0x60);
// var xFF = Vector128.Create((byte)0xFF);
// var src = (byte*)srcBytes;
// var dest = destBytes;
var x05 = Vector128.Create((byte)0x05);
var x09 = Vector128.Create((byte)0x09);
var x0A = Vector128.Create((byte)0x0A);
var x20 = Vector128.Create((byte)0x20);
var x30 = Vector128.Create((byte)0x30);
var x40 = Vector128.Create((byte)0x40);
var x41 = Vector128.Create((byte)0x41);
var x60 = Vector128.Create((byte)0x60);
var xFF = Vector128.Create((byte)0xFF);
var src = (byte*)srcBytes;
var dest = destBytes;
// var target = dest + FastMath.RoundDownTo16(destLength);
// int leftOk, rightOk;
// while (dest != target)
// {
// var a = LoadVector128(src).AsInt16();
// src += 16;
// var b = LoadVector128(src).AsInt16();
// src += 16;
// var c = LoadVector128(src).AsInt16();
// src += 16;
// var d = LoadVector128(src).AsInt16();
// src += 16;
var target = dest + FastMath.RoundDownTo16(destLength);
int leftOk, rightOk;
while (dest != target)
{
var a = LoadVector128(src).AsInt16();
src += 16;
var b = LoadVector128(src).AsInt16();
src += 16;
var c = LoadVector128(src).AsInt16();
src += 16;
var d = LoadVector128(src).AsInt16();
src += 16;
// var inputLeft = PackUnsignedSaturate(a, b);
// var inputRight = PackUnsignedSaturate(c, d);
var inputLeft = PackUnsignedSaturate(a, b);
var inputRight = PackUnsignedSaturate(c, d);
// var g40Left = CompareGreaterThan(inputLeft.AsSByte(), x40.AsSByte()).AsByte();
// var g60Left = CompareGreaterThan(inputLeft.AsSByte(), x60.AsSByte()).AsByte();
// var g40Right = CompareGreaterThan(inputRight.AsSByte(), x40.AsSByte()).AsByte();
// var g60Right = CompareGreaterThan(inputRight.AsSByte(), x60.AsSByte()).AsByte();
var g40Left = CompareGreaterThan(inputLeft.AsSByte(), x40.AsSByte()).AsByte();
var g60Left = CompareGreaterThan(inputLeft.AsSByte(), x60.AsSByte()).AsByte();
var g40Right = CompareGreaterThan(inputRight.AsSByte(), x40.AsSByte()).AsByte();
var g60Right = CompareGreaterThan(inputRight.AsSByte(), x60.AsSByte()).AsByte();
// var corr40Left = And(x41, g40Left);
// var corr60Left = And(x20, g60Left);
var corr40Left = And(x41, g40Left);
var corr60Left = And(x20, g60Left);
// var corr40Right = And(x41, g40Right);
// var corr60Right = And(x20, g60Right);
var corr40Right = And(x41, g40Right);
var corr60Right = And(x20, g60Right);
// var sub30Left = Subtract(inputLeft, x30);
// var sub40Left = Subtract(inputLeft, corr40Left);
var sub30Left = Subtract(inputLeft, x30);
var sub40Left = Subtract(inputLeft, corr40Left);
// var sub30Right = Subtract(inputRight, x30);
// var sub40Right = Subtract(inputRight, corr40Right);
var sub30Right = Subtract(inputRight, x30);
var sub40Right = Subtract(inputRight, corr40Right);
// var sub60Left = Subtract(sub40Left, corr60Left);
// var sub60Right = Subtract(sub40Right, corr60Right);
var sub60Left = Subtract(sub40Left, corr60Left);
var sub60Right = Subtract(sub40Right, corr60Right);
// var maskAfLeft = Or(g60Left, g40Left);
// var maskAfRight = Or(g60Right, g40Right);
var maskAfLeft = Or(g60Left, g40Left);
var maskAfRight = Or(g60Right, g40Right);
// var maskDigLeft = Xor(maskAfLeft, xFF);
// var maskDigRight = Xor(maskAfRight, xFF);
var maskDigLeft = Xor(maskAfLeft, xFF);
var maskDigRight = Xor(maskAfRight, xFF);
// var afLeft = And(sub60Left, maskAfLeft);
// var corrAfLeft = And(maskAfLeft, x0A);
var afLeft = And(sub60Left, maskAfLeft);
var corrAfLeft = And(maskAfLeft, x0A);
// var afRight = And(sub60Right, maskAfRight);
// var corrAfRight = And(maskAfRight, x0A);
var afRight = And(sub60Right, maskAfRight);
var corrAfRight = And(maskAfRight, x0A);
// var digLeft = And(sub30Left, maskDigLeft);
// var corrLeft = Add(afLeft, corrAfLeft);
var digLeft = And(sub30Left, maskDigLeft);
var corrLeft = Add(afLeft, corrAfLeft);
// var digRight = And(sub30Right, maskDigRight);
// var corrRight = Add(afRight, corrAfRight);
var digRight = And(sub30Right, maskDigRight);
var corrRight = Add(afRight, corrAfRight);
// var resultAfLeft = CompareGreaterThan(afLeft.AsSByte(), x05.AsSByte()).AsByte();
// var resultDigLeft = CompareGreaterThan(digLeft.AsSByte(), x09.AsSByte()).AsByte();
var resultAfLeft = CompareGreaterThan(afLeft.AsSByte(), x05.AsSByte()).AsByte();
var resultDigLeft = CompareGreaterThan(digLeft.AsSByte(), x09.AsSByte()).AsByte();
// var resultAfRight = CompareGreaterThan(afRight.AsSByte(), x05.AsSByte()).AsByte();
// var resultDigRight = CompareGreaterThan(digRight.AsSByte(), x09.AsSByte()).AsByte();
var resultAfRight = CompareGreaterThan(afRight.AsSByte(), x05.AsSByte()).AsByte();
var resultDigRight = CompareGreaterThan(digRight.AsSByte(), x09.AsSByte()).AsByte();
// var valueLeft = Or(corrLeft, digLeft);
// var valueRight = Or(corrRight, digRight);
var valueLeft = Or(corrLeft, digLeft);
var valueRight = Or(corrRight, digRight);
// var digAfLeft = Or(digLeft, afLeft);
// var digAfRight = Or(digRight, afRight);
var digAfLeft = Or(digLeft, afLeft);
var digAfRight = Or(digRight, afRight);
// var digAfOutOfRangeLeft = Or(resultAfLeft, resultDigLeft);
// var digAfOutOfRangeRight = Or(resultAfRight, resultDigRight);
var digAfOutOfRangeLeft = Or(resultAfLeft, resultDigLeft);
var digAfOutOfRangeRight = Or(resultAfRight, resultDigRight);
// var resLeft = Or(digAfLeft, digAfOutOfRangeLeft);
// var resRight = Or(digAfRight, digAfOutOfRangeRight);
var resLeft = Or(digAfLeft, digAfOutOfRangeLeft);
var resRight = Or(digAfRight, digAfOutOfRangeRight);
// var sh12Left = ShiftLeftLogical(valueLeft.AsUInt16(), 12).AsByte();
// var sh12Right = ShiftLeftLogical(valueRight.AsUInt16(), 12).AsByte();
var sh12Left = ShiftLeftLogical(valueLeft.AsUInt16(), 12).AsByte();
var sh12Right = ShiftLeftLogical(valueRight.AsUInt16(), 12).AsByte();
// var unp1 = ShiftRightLogical(Or(valueLeft, sh12Left).AsUInt16(), 8).AsByte();
// var unp2 = ShiftRightLogical(Or(valueRight, sh12Right).AsUInt16(), 8).AsByte();
var unp1 = ShiftRightLogical(Or(valueLeft, sh12Left).AsUInt16(), 8).AsByte();
var unp2 = ShiftRightLogical(Or(valueRight, sh12Right).AsUInt16(), 8).AsByte();
// var result = PackUnsignedSaturate(unp1.AsInt16(), unp2.AsInt16()).AsByte();
var result = PackUnsignedSaturate(unp1.AsInt16(), unp2.AsInt16()).AsByte();
// leftOk = MoveMask(resLeft);
// rightOk = MoveMask(resRight);
leftOk = MoveMask(resLeft);
rightOk = MoveMask(resRight);
// if ((leftOk | rightOk) != 0) goto Err;
if ((leftOk | rightOk) != 0) goto Err;
// Store(dest, result);
// dest += 16;
// }
Store(dest, result);
dest += 16;
}
// srcBytes = (char*)src;
// destBytes = dest;
// return true;
srcBytes = (char*)src;
destBytes = dest;
return true;
// Err:
// if (leftOk != 0)
// {
// srcBytes = (char*)(src - 64);
// destBytes = dest;
// return false;
// }
// else
// {
// Debug.Assert(rightOk != 0);
// srcBytes = (char*)(src - 32);
// destBytes = dest;
// return false;
// }
// }
// }
//}
Err:
if (leftOk != 0)
{
srcBytes = (char*)(src - 64);
destBytes = dest;
return false;
}
else
{
Debug.Assert(rightOk != 0);
srcBytes = (char*)(src - 32);
destBytes = dest;
return false;
}
}
}
}
//#endif
#endif
@@ -1,129 +1,129 @@
//#if NETCOREAPP3_0_OR_GREATER
#if NETCOREAPP3_0_OR_GREATER
//using System.Diagnostics;
//using System.Runtime.CompilerServices;
//using System.Runtime.Intrinsics;
//using static HexMate.VectorConstants;
//using static HexMate.VectorUtils;
//using static System.Runtime.Intrinsics.X86.Sse2;
//using static System.Runtime.Intrinsics.X86.Ssse3;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using static HexMate.VectorConstants;
using static HexMate.VectorUtils;
using static System.Runtime.Intrinsics.X86.Sse2;
using static System.Runtime.Intrinsics.X86.Ssse3;
//namespace HexMate;
namespace HexMate;
//internal static partial class Utf16HexParser
//{
// internal static unsafe class Ssse3
// {
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal static bool TryParse(ref char* srcBytes, ref byte* destBytes, int destLength)
// {
// Debug.Assert(System.Runtime.Intrinsics.X86.Ssse3.IsSupported);
internal static partial class Utf16HexParser
{
internal static unsafe class Ssse3
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TryParse(ref char* srcBytes, ref byte* destBytes, int destLength)
{
Debug.Assert(System.Runtime.Intrinsics.X86.Ssse3.IsSupported);
// var x0F = Vector128.Create((byte)0x0F);
// var x30 = Vector128.Create((byte)0x30);
// var x40 = Vector128.Create((byte)0x40);
// var x60 = Vector128.Create((byte)0x60);
// var xF0 = Vector128.Create((byte)0xF0);
// var validDig = ReadVector128(s_validDig);
// var validHex = ReadVector128(s_validHex);
// var evenBytes = ReadVector128(s_evenBytes);
// var oddBytes = ReadVector128(s_oddBytes);
// var src = (byte*)srcBytes;
// var dest = destBytes;
var x0F = Vector128.Create((byte)0x0F);
var x30 = Vector128.Create((byte)0x30);
var x40 = Vector128.Create((byte)0x40);
var x60 = Vector128.Create((byte)0x60);
var xF0 = Vector128.Create((byte)0xF0);
var validDig = ReadVector128(s_validDig);
var validHex = ReadVector128(s_validHex);
var evenBytes = ReadVector128(s_evenBytes);
var oddBytes = ReadVector128(s_oddBytes);
var src = (byte*)srcBytes;
var dest = destBytes;
// var target = dest + FastMath.RoundDownTo16(destLength);
// int leftOk, rightOk;
// while (dest != target)
// {
// var a = LoadVector128(src).AsInt16();
// src += 16;
// var b = LoadVector128(src).AsInt16();
// src += 16;
// var c = LoadVector128(src).AsInt16();
// src += 16;
// var d = LoadVector128(src).AsInt16();
// src += 16;
var target = dest + FastMath.RoundDownTo16(destLength);
int leftOk, rightOk;
while (dest != target)
{
var a = LoadVector128(src).AsInt16();
src += 16;
var b = LoadVector128(src).AsInt16();
src += 16;
var c = LoadVector128(src).AsInt16();
src += 16;
var d = LoadVector128(src).AsInt16();
src += 16;
// var inputLeft = PackUnsignedSaturate(a, b);
// var inputRight = PackUnsignedSaturate(c, d);
var inputLeft = PackUnsignedSaturate(a, b);
var inputRight = PackUnsignedSaturate(c, d);
// var hiNibbleLeft = And(inputLeft, xF0);
// var hiNibbleRight = And(inputRight, xF0);
var hiNibbleLeft = And(inputLeft, xF0);
var hiNibbleRight = And(inputRight, xF0);
// var upperHexMaskLeft = CompareEqual(hiNibbleLeft, x40);
// var lowerHexMaskLeft = CompareEqual(hiNibbleLeft, x60);
// var digitMaskLeft = CompareEqual(hiNibbleLeft, x30);
// var upperHexMaskRight = CompareEqual(hiNibbleRight, x40);
// var lowerHexMaskRight = CompareEqual(hiNibbleRight, x60);
// var digitMaskRight = CompareEqual(hiNibbleRight, x30);
var upperHexMaskLeft = CompareEqual(hiNibbleLeft, x40);
var lowerHexMaskLeft = CompareEqual(hiNibbleLeft, x60);
var digitMaskLeft = CompareEqual(hiNibbleLeft, x30);
var upperHexMaskRight = CompareEqual(hiNibbleRight, x40);
var lowerHexMaskRight = CompareEqual(hiNibbleRight, x60);
var digitMaskRight = CompareEqual(hiNibbleRight, x30);
// var hexMaskLeft = Or(upperHexMaskLeft, lowerHexMaskLeft);
// var hexMaskRight = Or(upperHexMaskRight, lowerHexMaskRight);
var hexMaskLeft = Or(upperHexMaskLeft, lowerHexMaskLeft);
var hexMaskRight = Or(upperHexMaskRight, lowerHexMaskRight);
// var hiNibbleValidLeft = Or(digitMaskLeft, hexMaskLeft);
// var hiNibbleValidRight = Or(digitMaskRight, hexMaskRight);
var hiNibbleValidLeft = Or(digitMaskLeft, hexMaskLeft);
var hiNibbleValidRight = Or(digitMaskRight, hexMaskRight);
// var digitsAndFLeft = Or(inputLeft, hexMaskLeft);
// var hexAndFLeft = Or(inputLeft, digitMaskLeft);
// var digitsAndFRight = Or(inputRight, hexMaskRight);
// var hexAndFRight = Or(inputRight, digitMaskRight);
var digitsAndFLeft = Or(inputLeft, hexMaskLeft);
var hexAndFLeft = Or(inputLeft, digitMaskLeft);
var digitsAndFRight = Or(inputRight, hexMaskRight);
var hexAndFRight = Or(inputRight, digitMaskRight);
// var okDig1 = Shuffle(validDig, digitsAndFLeft);
// var okHex1 = Shuffle(validHex, hexAndFLeft);
// var okDig2 = Shuffle(validDig, digitsAndFRight);
// var okHex2 = Shuffle(validHex, hexAndFRight);
var okDig1 = Shuffle(validDig, digitsAndFLeft);
var okHex1 = Shuffle(validHex, hexAndFLeft);
var okDig2 = Shuffle(validDig, digitsAndFRight);
var okHex2 = Shuffle(validHex, hexAndFRight);
// var loNibbleValidLeft = Or(okDig1, okHex1);
// var loNibbleValidRight = Or(okDig2, okHex2);
var loNibbleValidLeft = Or(okDig1, okHex1);
var loNibbleValidRight = Or(okDig2, okHex2);
// var validLeft = And(loNibbleValidLeft, hiNibbleValidLeft);
// var validRight = And(loNibbleValidRight, hiNibbleValidRight);
var validLeft = And(loNibbleValidLeft, hiNibbleValidLeft);
var validRight = And(loNibbleValidRight, hiNibbleValidRight);
// loNibbleValidLeft = And(loNibbleValidLeft, x0F);
// loNibbleValidRight = And(loNibbleValidRight, x0F);
loNibbleValidLeft = And(loNibbleValidLeft, x0F);
loNibbleValidRight = And(loNibbleValidRight, x0F);
// var evenBytesLeft = Shuffle(loNibbleValidLeft, evenBytes);
// var oddBytesLeft = Shuffle(loNibbleValidLeft, oddBytes);
// var evenBytesRight = Shuffle(loNibbleValidRight, evenBytes);
// var oddBytesRight = Shuffle(loNibbleValidRight, oddBytes);
var evenBytesLeft = Shuffle(loNibbleValidLeft, evenBytes);
var oddBytesLeft = Shuffle(loNibbleValidLeft, oddBytes);
var evenBytesRight = Shuffle(loNibbleValidRight, evenBytes);
var oddBytesRight = Shuffle(loNibbleValidRight, oddBytes);
// evenBytesLeft = ShiftLeftLogical(evenBytesLeft.AsUInt16(), 4).AsByte();
// evenBytesRight = ShiftLeftLogical(evenBytesRight.AsUInt16(), 4).AsByte();
evenBytesLeft = ShiftLeftLogical(evenBytesLeft.AsUInt16(), 4).AsByte();
evenBytesRight = ShiftLeftLogical(evenBytesRight.AsUInt16(), 4).AsByte();
// evenBytesLeft = Or(evenBytesLeft, oddBytesLeft);
// evenBytesRight = Or(evenBytesRight, oddBytesRight);
evenBytesLeft = Or(evenBytesLeft, oddBytesLeft);
evenBytesRight = Or(evenBytesRight, oddBytesRight);
// var result = UnpackLow(evenBytesLeft.AsInt64(), evenBytesRight.AsInt64()).AsByte();
var result = UnpackLow(evenBytesLeft.AsInt64(), evenBytesRight.AsInt64()).AsByte();
// leftOk = MoveMask(validLeft);
// rightOk = MoveMask(validRight);
leftOk = MoveMask(validLeft);
rightOk = MoveMask(validRight);
// if ((leftOk & rightOk) != 0xFFFF) goto Err;
if ((leftOk & rightOk) != 0xFFFF) goto Err;
// Store(dest, result);
// dest += 16;
// }
Store(dest, result);
dest += 16;
}
// srcBytes = (char*)src;
// destBytes = dest;
// return true;
srcBytes = (char*)src;
destBytes = dest;
return true;
// Err:
// if (leftOk != 0xFFFF)
// {
// srcBytes = (char*)(src - 64);
// destBytes = dest;
// return false;
// }
// else
// {
// Debug.Assert(rightOk != 0xFFFF);
// srcBytes = (char*)(src - 32);
// destBytes = dest;
// return false;
// }
// }
// }
//}
Err:
if (leftOk != 0xFFFF)
{
srcBytes = (char*)(src - 64);
destBytes = dest;
return false;
}
else
{
Debug.Assert(rightOk != 0xFFFF);
srcBytes = (char*)(src - 32);
destBytes = dest;
return false;
}
}
}
}
//#endif
#endif