test: add tests for ReverseElements (#73)

This commit is contained in:
Oliver Booth 2023-04-01 23:48:01 +01:00
parent 6f16c0df3c
commit 586057ba3d
No known key found for this signature in database
GPG Key ID: 20BEB9DC87961025
2 changed files with 51 additions and 12 deletions

View File

@ -82,5 +82,33 @@ public class IntrinsicTests
Assert.AreEqual(expectedResult, result);
}
[TestMethod]
public void ReverseElements_ShouldReturnExpectedVector128Result_GivenInputVector()
{
var mock = new Mock<ISse2SupportProvider>();
mock.Setup(provider => provider.IsSupported).Returns(true);
var inputVector = Vector128.Create(42UL, 69UL);
var expectedResult = Vector128.Create(69UL, 42UL);
Vector128<ulong> result = inputVector.ReverseElementsInternal(mock.Object);
Assert.AreEqual(expectedResult, result);
}
[TestMethod]
public void ReverseElements_ShouldReturnExpectedVector128Result_WhenSse2NotSupported()
{
var mock = new Mock<ISse2SupportProvider>();
mock.Setup(provider => provider.IsSupported).Returns(false);
var inputVector = Vector128.Create(42UL, 69UL);
var expectedResult = Vector128.Create(69UL, 42UL);
Vector128<ulong> result = inputVector.ReverseElementsInternal(mock.Object);
Assert.AreEqual(expectedResult, result);
}
}
#endif

View File

@ -1,4 +1,4 @@
#if NETCOREAPP3_0_OR_GREATER
#if NETCOREAPP3_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
@ -115,19 +115,10 @@ public static class IntrinsicExtensions
[Pure]
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
[ExcludeFromCodeCoverage]
public static Vector128<ulong> ReverseElements(this Vector128<ulong> vector)
{
if (Sse2.IsSupported)
{
return Sse2.Shuffle(vector.AsDouble(), vector.AsDouble(), 0b01).AsUInt64();
}
Vector128<ulong> output = IntrinsicUtility.GetUninitializedVector128<ulong>();
Unsafe.As<Vector128<ulong>, ulong>(ref output) = Unsafe.Add(ref Unsafe.As<Vector128<ulong>, ulong>(ref vector), 1);
Unsafe.Add(ref Unsafe.As<Vector128<ulong>, ulong>(ref output), 1) = Unsafe.As<Vector128<ulong>, ulong>(ref vector);
return output;
return ReverseElementsInternal(vector, new SystemSse2SupportProvider());
}
[Pure]
@ -182,5 +173,25 @@ public static class IntrinsicExtensions
return output;
}
[Pure]
[CLSCompliant(false)]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
internal static Vector128<ulong> ReverseElementsInternal(this Vector128<ulong> vector, ISse2SupportProvider? supportProvider)
{
supportProvider ??= new SystemSse2SupportProvider();
if (supportProvider.IsSupported)
{
return Sse2.Shuffle(vector.AsDouble(), vector.AsDouble(), 0b01).AsUInt64();
}
Vector128<ulong> output = IntrinsicUtility.GetUninitializedVector128<ulong>();
Unsafe.As<Vector128<ulong>, ulong>(ref output) = Unsafe.Add(ref Unsafe.As<Vector128<ulong>, ulong>(ref vector), 1);
Unsafe.Add(ref Unsafe.As<Vector128<ulong>, ulong>(ref output), 1) = Unsafe.As<Vector128<ulong>, ulong>(ref vector);
return output;
}
}
#endif