Add test cases for Pclmulqdq intrinsic
authorFei Peng <fei.peng@intel.com>
Wed, 5 Sep 2018 22:40:51 +0000 (15:40 -0700)
committerTanner Gooding <tagoo@outlook.com>
Mon, 10 Sep 2018 19:55:37 +0000 (12:55 -0700)
15 files changed:
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.0.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.1.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.129.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.Int64.17.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.0.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.1.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.129.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/CarrylessMultiply.UInt64.17.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_r.csproj [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Pclmulqdq_ro.csproj [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Pclmulqdq/Program.Pclmulqdq.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
tests/src/JIT/HardwareIntrinsics/X86/Shared/PclmulqdqOpTest.template [new file with mode: 0644]

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 (file)
index 0000000..ee8eda6
--- /dev/null
@@ -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<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                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<Vector128<Int64>>() / 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<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyInt640()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyInt640()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_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<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Int64>>(_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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+                                        (byte)0
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)0
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)0
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_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<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            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)}<Int64>(Vector128<Int64>, 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 (file)
index 0000000..de31aa0
--- /dev/null
@@ -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<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                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<Vector128<Int64>>() / 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<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyInt641()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyInt641()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_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<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Int64>>(_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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+                                        (byte)1
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)1
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)1
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_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<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            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)}<Int64>(Vector128<Int64>, 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 (file)
index 0000000..76be93f
--- /dev/null
@@ -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<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                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<Vector128<Int64>>() / 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<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyInt64129()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyInt64129()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_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<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Int64>>(_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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+                                        (byte)129
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)129
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)129
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_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<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            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)}<Int64>(Vector128<Int64>, 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 (file)
index 0000000..d5b2f31
--- /dev/null
@@ -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<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                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<Vector128<Int64>>() / 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<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyInt6416()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyInt6416()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_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<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Int64>>(_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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+                                        (byte)16
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)16
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)16
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_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<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            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)}<Int64>(Vector128<Int64>, 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 (file)
index 0000000..990b446
--- /dev/null
@@ -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<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                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<Vector128<Int64>>() / 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<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyInt6417()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyInt6417()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_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<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<Int64>>(_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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+                                        (byte)17
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)17
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+                                        (byte)17
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(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<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_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<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            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)}<Int64>(Vector128<Int64>, 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 (file)
index 0000000..4502811
--- /dev/null
@@ -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<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                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<Vector128<UInt64>>() / 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<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyUInt640()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyUInt640()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_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<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<UInt64>>(_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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+                                        (byte)0
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)0
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)0
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_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<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            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)}<UInt64>(Vector128<UInt64>, 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 (file)
index 0000000..f267e19
--- /dev/null
@@ -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<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                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<Vector128<UInt64>>() / 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<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyUInt641()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyUInt641()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_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<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<UInt64>>(_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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+                                        (byte)1
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)1
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)1
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_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<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            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)}<UInt64>(Vector128<UInt64>, 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 (file)
index 0000000..b5b5e9e
--- /dev/null
@@ -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<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                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<Vector128<UInt64>>() / 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<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyUInt64129()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyUInt64129()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_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<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<UInt64>>(_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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+                                        (byte)129
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)129
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)129
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_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<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            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)}<UInt64>(Vector128<UInt64>, 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 (file)
index 0000000..a662ef3
--- /dev/null
@@ -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<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                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<Vector128<UInt64>>() / 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<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyUInt6416()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyUInt6416()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_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<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<UInt64>>(_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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+                                        (byte)16
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)16
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)16
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_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<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            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)}<UInt64>(Vector128<UInt64>, 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 (file)
index 0000000..29b0072
--- /dev/null
@@ -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<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                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<Vector128<UInt64>>() / 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<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static PclmulqdqOpTest__CarrylessMultiplyUInt6417()
+        {
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public PclmulqdqOpTest__CarrylessMultiplyUInt6417()
+        {
+            Succeeded = true;
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_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<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                Unsafe.Read<Vector128<UInt64>>(_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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+                                        Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+                                        (byte)17
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)17
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+                                     .Invoke(null, new object[] {
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+                                        Pclmulqdq.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+                                        (byte)17
+                                     });
+
+            Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(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<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_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<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            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)}<UInt64>(Vector128<UInt64>, 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 (file)
index 0000000..5f60cd4
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <PropertyGroup>
+    <DebugType>Embedded</DebugType>
+    <Optimize></Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CarrylessMultiply.Int64.0.cs" />
+    <Compile Include="CarrylessMultiply.Int64.1.cs" />
+    <Compile Include="CarrylessMultiply.Int64.16.cs" />
+    <Compile Include="CarrylessMultiply.Int64.17.cs" />
+    <Compile Include="CarrylessMultiply.Int64.129.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.0.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.1.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.16.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.17.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.129.cs" />
+    <Compile Include="Program.Pclmulqdq.cs" />
+    <Compile Include="..\Shared\Program.cs" />
+    <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
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 (file)
index 0000000..8b87e01
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <PropertyGroup>
+    <DebugType>Embedded</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CarrylessMultiply.Int64.0.cs" />
+    <Compile Include="CarrylessMultiply.Int64.1.cs" />
+    <Compile Include="CarrylessMultiply.Int64.16.cs" />
+    <Compile Include="CarrylessMultiply.Int64.17.cs" />
+    <Compile Include="CarrylessMultiply.Int64.129.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.0.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.1.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.16.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.17.cs" />
+    <Compile Include="CarrylessMultiply.UInt64.129.cs" />
+    <Compile Include="Program.Pclmulqdq.cs" />
+    <Compile Include="..\Shared\Program.cs" />
+    <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
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 (file)
index 0000000..422b803
--- /dev/null
@@ -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<string, Action>() {
+                ["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,
+            };
+        }
+    }
+}
index 28bde46..c94fd57 100644 (file)
@@ -899,6 +899,20 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
     ("AesImmOpTest.template",   new Dictionary<string, string> { ["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<string, string> templateData)[] PclmulqdqInputs = new []
+{
+    ("PclmulqdqOpTest.template",   new Dictionary<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> { ["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<string, string> 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 (file)
index 0000000..352cdc3
--- /dev/null
@@ -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<byte>(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);
+            }
+        }
+
+    }
+}