From: Fei Peng Date: Wed, 5 Sep 2018 22:40:51 +0000 (-0700) Subject: Add test cases for Pclmulqdq intrinsic X-Git-Tag: accepted/tizen/unified/20190422.045933~1247 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6d02d3a09588b062984e1e32f281318394b91c9a;p=platform%2Fupstream%2Fcoreclr.git Add test cases for Pclmulqdq intrinsic --- diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.0.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.0.cs new file mode 100644 index 0000000..ee8eda6 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.0.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyInt640() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyInt640(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyInt640 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyInt640 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 0); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[2] {-2, -20}; + private static Int64[] _data2 = new Int64[2] {25, 65535}; + private static Int64[] _expectedRet = new Int64[2] {-18, 8}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyInt640() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyInt640() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)0 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)0 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)0 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyInt640(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Int64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 0): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.1.cs new file mode 100644 index 0000000..de31aa0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.1.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyInt641() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyInt641 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyInt641 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[2] {-2, -20}; + private static Int64[] _data2 = new Int64[2] {25, 65535}; + private static Int64[] _expectedRet = new Int64[2] {-436, 8}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyInt641() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyInt641() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyInt641(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Int64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.129.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.129.cs new file mode 100644 index 0000000..76be93f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.129.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyInt64129() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyInt64129(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyInt64129 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyInt64129 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 129); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[2] {-2, -20}; + private static Int64[] _data2 = new Int64[2] {25, 65535}; + private static Int64[] _expectedRet = new Int64[2] {-436, 8}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyInt64129() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyInt64129() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)129 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)129 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)129 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyInt64129(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Int64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 129): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.16.cs new file mode 100644 index 0000000..d5b2f31 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.16.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyInt6416() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyInt6416(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyInt6416 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyInt6416 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 16); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[2] {-2, -20}; + private static Int64[] _data2 = new Int64[2] {25, 65535}; + private static Int64[] _expectedRet = new Int64[2] {43690, 21845}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyInt6416() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyInt6416() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyInt6416(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Int64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 16): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.17.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.17.cs new file mode 100644 index 0000000..990b446 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.17.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyInt6417() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyInt6417(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyInt6417 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyInt6417 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 17); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data1 = new Int64[2] {-2, -20}; + private static Int64[] _data2 = new Int64[2] {25, 65535}; + private static Int64[] _expectedRet = new Int64[2] {961188, 21845}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyInt6417() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyInt6417() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)17 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)17 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)), + (byte)17 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyInt6417(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Int64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 17): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.0.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.0.cs new file mode 100644 index 0000000..4502811 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.0.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyUInt640() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt640(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyUInt640 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyUInt640 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 0); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[2] {2, 20}; + private static UInt64[] _data2 = new UInt64[2] {25, 95}; + private static UInt64[] _expectedRet = new UInt64[2] {50, 0}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyUInt640() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyUInt640() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)0 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)0 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)0 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 0 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt640(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 0); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 0): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.1.cs new file mode 100644 index 0000000..f267e19 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.1.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyUInt641() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt641(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyUInt641 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyUInt641 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 1); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[2] {2, 20}; + private static UInt64[] _data2 = new UInt64[2] {25, 95}; + private static UInt64[] _expectedRet = new UInt64[2] {500, 0}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyUInt641() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyUInt641() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)1 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 1 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt641(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 1); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 1): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.129.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.129.cs new file mode 100644 index 0000000..b5b5e9e --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.129.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyUInt64129() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt64129(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyUInt64129 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyUInt64129 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 129); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[2] {2, 20}; + private static UInt64[] _data2 = new UInt64[2] {25, 95}; + private static UInt64[] _expectedRet = new UInt64[2] {500, 0}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyUInt64129() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyUInt64129() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)129 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)129 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)129 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 129 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt64129(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 129); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 129): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.16.cs new file mode 100644 index 0000000..a662ef3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.16.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyUInt6416() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt6416(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyUInt6416 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyUInt6416 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 16); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[2] {2, 20}; + private static UInt64[] _data2 = new UInt64[2] {25, 95}; + private static UInt64[] _expectedRet = new UInt64[2] {190, 0}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyUInt6416() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyUInt6416() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)16 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 16 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt6416(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 16); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 16): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.17.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.17.cs new file mode 100644 index 0000000..29b0072 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.17.cs @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void CarrylessMultiplyUInt6417() + { + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt6417(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Pclmulqdq.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__CarrylessMultiplyUInt6417 + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__CarrylessMultiplyUInt6417 testClass) + { + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 17); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data1 = new UInt64[2] {2, 20}; + private static UInt64[] _data2 = new UInt64[2] {25, 95}; + private static UInt64[] _expectedRet = new UInt64[2] {1164, 0}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static PclmulqdqOpTest__CarrylessMultiplyUInt6417() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public PclmulqdqOpTest__CarrylessMultiplyUInt6417() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Pclmulqdq.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Pclmulqdq.CarrylessMultiply( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Pclmulqdq.CarrylessMultiply( + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr), + (byte)17 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)17 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Pclmulqdq).GetMethod(nameof(Pclmulqdq.CarrylessMultiply), new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)), + Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)), + (byte)17 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Pclmulqdq.CarrylessMultiply( + _clsVar1, + _clsVar2, + 17 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Pclmulqdq.CarrylessMultiply(left, right, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)); + var right = Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)); + var result = Pclmulqdq.CarrylessMultiply(left, right, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__CarrylessMultiplyUInt6417(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Pclmulqdq.CarrylessMultiply(_fld1, _fld2, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Pclmulqdq.CarrylessMultiply(test._fld1, test._fld2, 17); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(UInt64[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Pclmulqdq)}.{nameof(Pclmulqdq.CarrylessMultiply)}(Vector128, 17): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_r.csproj new file mode 100644 index 0000000..5f60cd4 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_r.csproj @@ -0,0 +1,46 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + Embedded + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_ro.csproj new file mode 100644 index 0000000..8b87e01 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_ro.csproj @@ -0,0 +1,46 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + Embedded + True + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Program.Pclmulqdq.cs b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Program.Pclmulqdq.cs new file mode 100644 index 0000000..422b803 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Program.Pclmulqdq.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + static Program() + { + TestList = new Dictionary() { + ["CarrylessMultiply.UInt64.0"] = CarrylessMultiplyUInt640, + ["CarrylessMultiply.UInt64.1"] = CarrylessMultiplyUInt641, + ["CarrylessMultiply.UInt64.16"] = CarrylessMultiplyUInt6416, + ["CarrylessMultiply.UInt64.17"] = CarrylessMultiplyUInt6417, + ["CarrylessMultiply.UInt64.129"] = CarrylessMultiplyUInt64129, + ["CarrylessMultiply.Int64.0"] = CarrylessMultiplyInt640, + ["CarrylessMultiply.Int64.1"] = CarrylessMultiplyInt641, + ["CarrylessMultiply.Int64.16"] = CarrylessMultiplyInt6416, + ["CarrylessMultiply.Int64.17"] = CarrylessMultiplyInt6417, + ["CarrylessMultiply.Int64.129"] = CarrylessMultiplyInt64129, + }; + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx index 28bde46..c94fd57 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx @@ -899,6 +899,20 @@ private static readonly (string templateFileName, Dictionary tem ("AesImmOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "KeygenAssist", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x85, 0x6e, 0x26, 0x7c, 0x6b, 0x26, 0x7c, 0x85, 0xea, 0xac, 0xee, 0xc4, 0xa9, 0xee, 0xc4, 0xea}"}), }; +private static readonly (string templateFileName, Dictionary templateData)[] PclmulqdqInputs = new [] +{ + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["Input1"] = "{2, 20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 95}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{50, 0}", ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["Input1"] = "{2, 20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 95}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{500, 0}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "16", ["LargestVectorSize"] = "16", ["Input1"] = "{2, 20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 95}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{190, 0}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "17", ["LargestVectorSize"] = "16", ["Input1"] = "{2, 20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 95}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{1164, 0}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64",["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "129", ["LargestVectorSize"] = "16",["Input1"] = "{2, 20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 95}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{500, 0}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["Input1"] = "{-2, -20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 65535}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{-18, 8}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["Input1"] = "{-2, -20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 65535}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{-436, 8}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "16", ["LargestVectorSize"] = "16", ["Input1"] = "{-2, -20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 65535}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{43690, 21845}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "17", ["LargestVectorSize"] = "16", ["Input1"] = "{-2, -20}", ["Input1Size"] = "2" ,["Input2"] = "{25, 65535}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{961188, 21845}" , ["ExpectedRetSize"] = "2"}), + ("PclmulqdqOpTest.template", new Dictionary { ["Isa"] = "Pclmulqdq", ["LoadIsa"] = "Pclmulqdq", ["Method"] = "CarrylessMultiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "129", ["LargestVectorSize"] = "16", ["Input1"] = "{-2, -20}", ["Input1Size"] = "2" ,["Input2"] ="{25, 65535}", ["Input2Size"] = "2" ,["ExpectedRet"] = "{-436, 8}" , ["ExpectedRetSize"] = "2"}), +}; + private const string ValidateBmi2ParallelBitComment = @" // The validation logic defined here for Bmi2.ParallelBitDeposit and Bmi2.ParallelBitExtract is // based on the 'Operation' pseudo-code defined for the pdep and pext instruction in the 'Intel® @@ -1029,7 +1043,7 @@ private static bool isImmTemplate(string name) name == "ExtractScalarTest.template" || name == "InsertVector128Test.template" || name == "ExtractVector128Test.template" || name == "InsertLoadTest.template" || name == "ExtractStoreTest.template" || name == "ImmBinOpTest.template" || - name == "AesImmOpTest.template"; + name == "AesImmOpTest.template" || name == "PclmulqdqOpTest.template"; } private static void ProcessInput(StreamWriter testListFile, string groupName, (string templateFileName, Dictionary templateData) input) @@ -1086,3 +1100,4 @@ ProcessInputs("Fma_Vector256", Fma_Vector256Inputs); ProcessInputs("Bmi1", Bmi1Inputs); ProcessInputs("Bmi2", Bmi2Inputs); ProcessInputs("Aes", AesInputs); +ProcessInputs("Pclmulqdq", PclmulqdqInputs); diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/PclmulqdqOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/PclmulqdqOpTest.template new file mode 100644 index 0000000..352cdc3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/PclmulqdqOpTest.template @@ -0,0 +1,378 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void {Method}{RetBaseType}{Imm}() + { + var test = new PclmulqdqOpTest__{Method}{RetBaseType}{Imm}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local class works + test.RunClassLclFldScenario(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class PclmulqdqOpTest__{Method}{RetBaseType}{Imm} + { + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op2VectorType}<{Op2BaseType}> _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + return testStruct; + } + + public void RunStructFldScenario(PclmulqdqOpTest__{Method}{RetBaseType}{Imm} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[{Input1Size}] {Input1}; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[{Input2Size}] {Input2}; + private static {RetBaseType}[] _expectedRet = new {RetBaseType}[{ExpectedRetSize}] {ExpectedRet}; + + private static {Op1VectorType}<{Op1BaseType}> _clsVar1; + private static {Op2VectorType}<{Op2BaseType}> _clsVar2; + + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op2VectorType}<{Op2BaseType}> _fld2; + + private SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable; + + static PclmulqdqOpTest__{Method}{RetBaseType}{Imm}() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + } + + public PclmulqdqOpTest__{Method}{RetBaseType}{Imm}() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>()); + + _dataTable = new SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = {Isa}.{Method}( + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) }) + .Invoke(null, new object[] { + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar1, + _clsVar2, + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var result = {Isa}.{Method}(left, right, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)); + var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)); + var result = {Isa}.{Method}(left, right, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)); + var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)); + var result = {Isa}.{Method}(left, right, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new PclmulqdqOpTest__{Method}{RetBaseType}{Imm}(); + var result = {Isa}.{Method}(test._fld1, test._fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult({RetBaseType}[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Imm}): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" expectedRet: ({string.Join(", ", _expectedRet)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + } + } + + } +}