From 33b82dd4dfdffbbce11a7175e2616e9bcd245b1e Mon Sep 17 00:00:00 2001 From: Fei Peng Date: Thu, 23 Aug 2018 13:50:02 -0700 Subject: [PATCH] Add test cases for AES intrinsic --- .../JIT/HardwareIntrinsics/X86/Aes/Aes_r.csproj | 43 +++ .../JIT/HardwareIntrinsics/X86/Aes/Aes_ro.csproj | 43 +++ .../JIT/HardwareIntrinsics/X86/Aes/Decrypt.Byte.cs | 374 +++++++++++++++++++++ .../HardwareIntrinsics/X86/Aes/DecryptLast.Byte.cs | 374 +++++++++++++++++++++ .../JIT/HardwareIntrinsics/X86/Aes/Encrypt.Byte.cs | 374 +++++++++++++++++++++ .../HardwareIntrinsics/X86/Aes/EncryptLast.Byte.cs | 374 +++++++++++++++++++++ .../X86/Aes/InverseMixColumns.Byte.cs | 356 ++++++++++++++++++++ .../X86/Aes/KeygenAssist.Byte.5.cs | 362 ++++++++++++++++++++ .../JIT/HardwareIntrinsics/X86/Aes/Program.Aes.cs | 24 ++ .../X86/Shared/AesBinOpTest.template | 374 +++++++++++++++++++++ .../X86/Shared/AesImmOpTest.template | 362 ++++++++++++++++++++ .../X86/Shared/AesUnOpTest.template | 356 ++++++++++++++++++++ .../X86/Shared/GenerateTests.csx | 14 +- 13 files changed, 3429 insertions(+), 1 deletion(-) create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_r.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_ro.csproj create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/Decrypt.Byte.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/DecryptLast.Byte.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/Encrypt.Byte.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/EncryptLast.Byte.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/InverseMixColumns.Byte.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/KeygenAssist.Byte.5.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Aes/Program.Aes.cs create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Shared/AesBinOpTest.template create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Shared/AesImmOpTest.template create mode 100644 tests/src/JIT/HardwareIntrinsics/X86/Shared/AesUnOpTest.template diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_r.csproj new file mode 100644 index 0000000..356590b --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_r.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + Embedded + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_ro.csproj new file mode 100644 index 0000000..4563e71 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Aes_ro.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + Embedded + True + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Aes/Decrypt.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Decrypt.Byte.cs new file mode 100644 index 0000000..1a4a0d1 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Decrypt.Byte.cs @@ -0,0 +1,374 @@ +// 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 DecryptByte() + { + var test = new SimpleBinaryOpTest__DecryptByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Aes.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 (Aes.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 (Aes.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 SimpleBinaryOpTest__DecryptByte + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__DecryptByte testClass) + { + var result = Aes.Decrypt(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + + private static Byte[] _data1 = new Byte[16] {0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; + private static Byte[] _data2 = new Byte[16] {0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}; + private static Byte[] _expectedRet = new Byte[16] {0x8f, 0xc4, 0xfe, 0x76, 0x51, 0x4f, 0x4e, 0x04, 0xee, 0x39, 0xda, 0x81, 0xa3, 0xcf, 0x7e, 0xb5}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__DecryptByte() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__DecryptByte() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.Decrypt( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.Decrypt( + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Aes.Decrypt( + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.Decrypt), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.Decrypt), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Aes).GetMethod(nameof(Aes.Decrypt), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.Decrypt( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.Decrypt(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.Decrypt(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.Decrypt(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__DecryptByte(); + var result = Aes.Decrypt(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.Decrypt(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.Decrypt(test._fld1, test._fld2); + + 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 = "") + { + + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + + private void ValidateResult(Byte[] 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(Aes)}.{nameof(Aes.Decrypt)}(Vector128, Vector128): {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/Aes/DecryptLast.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/DecryptLast.Byte.cs new file mode 100644 index 0000000..b8e76e3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/DecryptLast.Byte.cs @@ -0,0 +1,374 @@ +// 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 DecryptLastByte() + { + var test = new SimpleBinaryOpTest__DecryptLastByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Aes.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 (Aes.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 (Aes.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 SimpleBinaryOpTest__DecryptLastByte + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__DecryptLastByte testClass) + { + var result = Aes.DecryptLast(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + + private static Byte[] _data1 = new Byte[16] {0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; + private static Byte[] _data2 = new Byte[16] {0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}; + private static Byte[] _expectedRet = new Byte[16] {0x9e, 0xbf, 0x72, 0x90, 0x7d, 0xd5, 0xca, 0x36, 0x93, 0xa4, 0xa4, 0x1f, 0x98, 0xdd, 0x10, 0xf2}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__DecryptLastByte() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__DecryptLastByte() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.DecryptLast( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.DecryptLast( + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Aes.DecryptLast( + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.DecryptLast), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.DecryptLast), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Aes).GetMethod(nameof(Aes.DecryptLast), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.DecryptLast( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.DecryptLast(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.DecryptLast(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.DecryptLast(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__DecryptLastByte(); + var result = Aes.DecryptLast(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.DecryptLast(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.DecryptLast(test._fld1, test._fld2); + + 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 = "") + { + + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + + private void ValidateResult(Byte[] 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(Aes)}.{nameof(Aes.DecryptLast)}(Vector128, Vector128): {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/Aes/Encrypt.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Encrypt.Byte.cs new file mode 100644 index 0000000..3d72a0f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Encrypt.Byte.cs @@ -0,0 +1,374 @@ +// 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 EncryptByte() + { + var test = new SimpleBinaryOpTest__EncryptByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Aes.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 (Aes.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 (Aes.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 SimpleBinaryOpTest__EncryptByte + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__EncryptByte testClass) + { + var result = Aes.Encrypt(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + + private static Byte[] _data1 = new Byte[16] {0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; + private static Byte[] _data2 = new Byte[16] {0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}; + private static Byte[] _expectedRet = new Byte[16] {0xed, 0x42, 0xc4, 0xdf, 0x57, 0x0e, 0xab, 0x16, 0x33, 0x43, 0x50, 0x84, 0x18, 0xee, 0xe4, 0x28}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__EncryptByte() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__EncryptByte() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.Encrypt( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.Encrypt( + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Aes.Encrypt( + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.Encrypt), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.Encrypt), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Aes).GetMethod(nameof(Aes.Encrypt), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.Encrypt( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.Encrypt(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.Encrypt(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.Encrypt(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__EncryptByte(); + var result = Aes.Encrypt(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.Encrypt(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.Encrypt(test._fld1, test._fld2); + + 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 = "") + { + + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + + private void ValidateResult(Byte[] 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(Aes)}.{nameof(Aes.Encrypt)}(Vector128, Vector128): {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/Aes/EncryptLast.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/EncryptLast.Byte.cs new file mode 100644 index 0000000..e6a79f9 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/EncryptLast.Byte.cs @@ -0,0 +1,374 @@ +// 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 EncryptLastByte() + { + var test = new SimpleBinaryOpTest__EncryptLastByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Aes.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 (Aes.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 (Aes.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 SimpleBinaryOpTest__EncryptLastByte + { + private struct TestStruct + { + public Vector128 _fld1; + public Vector128 _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleBinaryOpTest__EncryptLastByte testClass) + { + var result = Aes.EncryptLast(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + + private static Byte[] _data1 = new Byte[16] {0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; + private static Byte[] _data2 = new Byte[16] {0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}; + private static Byte[] _expectedRet = new Byte[16] {0x20, 0xb3, 0x7a, 0x5d, 0xf2, 0x7d, 0xdd, 0xb6, 0xf8, 0x60, 0xc8, 0xf4, 0x8c, 0xf9, 0x04, 0x4b}; + + private static Vector128 _clsVar1; + private static Vector128 _clsVar2; + + private Vector128 _fld1; + private Vector128 _fld2; + + private SimpleBinaryOpTest__DataTable _dataTable; + + static SimpleBinaryOpTest__EncryptLastByte() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleBinaryOpTest__EncryptLastByte() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld1), ref Unsafe.As(ref _data1[0]), (uint)Unsafe.SizeOf>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld2), ref Unsafe.As(ref _data2[0]), (uint)Unsafe.SizeOf>()); + + _dataTable = new SimpleBinaryOpTest__DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.EncryptLast( + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.EncryptLast( + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Aes.EncryptLast( + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.EncryptLast), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArray1Ptr), + Unsafe.Read>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.EncryptLast), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Aes).GetMethod(nameof(Aes.EncryptLast), new Type[] { typeof(Vector128), typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)), + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.EncryptLast( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var left = Unsafe.Read>(_dataTable.inArray1Ptr); + var right = Unsafe.Read>(_dataTable.inArray2Ptr); + var result = Aes.EncryptLast(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var left = Aes.LoadVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.EncryptLast(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var left = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)); + var right = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)); + var result = Aes.EncryptLast(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__EncryptLastByte(); + var result = Aes.EncryptLast(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.EncryptLast(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.EncryptLast(test._fld1, test._fld2); + + 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 = "") + { + + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + + private void ValidateResult(Byte[] 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(Aes)}.{nameof(Aes.EncryptLast)}(Vector128, Vector128): {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/Aes/InverseMixColumns.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/InverseMixColumns.Byte.cs new file mode 100644 index 0000000..9a5b8c3 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/InverseMixColumns.Byte.cs @@ -0,0 +1,356 @@ +// 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 InverseMixColumnsByte() + { + var test = new SimpleUnaryOpTest__InverseMixColumnsByte(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Aes.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 (Aes.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 (Aes.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 SimpleUnaryOpTest__InverseMixColumnsByte + { + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__InverseMixColumnsByte testClass) + { + var result = Aes.InverseMixColumns(_fld); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[16] {0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; + private static Byte[] _expectedRet = new Byte[16] {0xa0, 0x0a, 0xe4, 0x4e, 0x28, 0x82, 0x6c, 0xc6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InverseMixColumnsByte() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InverseMixColumnsByte() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.InverseMixColumns( + Unsafe.Read>(_dataTable.inArrayPtr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult( _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.InverseMixColumns( + Aes.LoadVector128((Byte*)(_dataTable.inArrayPtr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Aes.InverseMixColumns( + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.InverseMixColumns), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.InverseMixColumns), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadVector128((Byte*)(_dataTable.inArrayPtr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Aes).GetMethod(nameof(Aes.InverseMixColumns), new Type[] { typeof(Vector128) }) + .Invoke(null, new object[] { + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.InverseMixColumns( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Aes.InverseMixColumns(firstOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = Aes.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Aes.InverseMixColumns(firstOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var firstOp = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Aes.InverseMixColumns(firstOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__InverseMixColumnsByte(); + var result = Aes.InverseMixColumns(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.InverseMixColumns(_fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.InverseMixColumns(test._fld); + + 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 = "") + { + + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Byte[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Aes)}.{nameof(Aes.InverseMixColumns)}(Vector128): {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/Aes/KeygenAssist.Byte.5.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/KeygenAssist.Byte.5.cs new file mode 100644 index 0000000..4b8be2a --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/KeygenAssist.Byte.5.cs @@ -0,0 +1,362 @@ +// 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 KeygenAssistByte5() + { + var test = new ImmUnaryOpTest__KeygenAssistByte5(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Aes.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 (Aes.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 (Aes.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 ImmUnaryOpTest__KeygenAssistByte5 + { + private struct TestStruct + { + public Vector128 _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref testStruct._fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__KeygenAssistByte5 testClass) + { + var result = Aes.KeygenAssist(_fld, 5); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = 16; + + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[16] {0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; + private static Byte[] _expectedRet = new Byte[16] {0x85, 0x6e, 0x26, 0x7c, 0x6b, 0x26, 0x7c, 0x85, 0xea, 0xac, 0xee, 0xc4, 0xa9, 0xee, 0xc4, 0xea}; + + private static Vector128 _clsVar; + + private Vector128 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static ImmUnaryOpTest__KeygenAssistByte5() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public ImmUnaryOpTest__KeygenAssistByte5() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Aes.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var result = Aes.KeygenAssist( + Unsafe.Read>(_dataTable.inArrayPtr), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + var result = Aes.KeygenAssist( + Aes.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned)); + + var result = Aes.KeygenAssist( + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)), + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var result = typeof(Aes).GetMethod(nameof(Aes.KeygenAssist), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load)); + + var result = typeof(Aes).GetMethod(nameof(Aes.KeygenAssist), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Aes.LoadVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned)); + + var result = typeof(Aes).GetMethod(nameof(Aes.KeygenAssist), new Type[] { typeof(Vector128), typeof(byte) }) + .Invoke(null, new object[] { + Aes.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)), + (byte)5 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = Aes.KeygenAssist( + _clsVar, + 5 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Aes.KeygenAssist(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = Aes.LoadVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Aes.KeygenAssist(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var firstOp = Aes.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)); + var result = Aes.KeygenAssist(firstOp, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__KeygenAssistByte5(); + var result = Aes.KeygenAssist(test._fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = Aes.KeygenAssist(_fld, 5); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = Aes.KeygenAssist(test._fld, 5); + + 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 = "") + { + + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult(Byte[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Aes)}.{nameof(Aes.KeygenAssist)}(Vector128, 5): {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/Aes/Program.Aes.cs b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Program.Aes.cs new file mode 100644 index 0000000..27a7c83 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Aes/Program.Aes.cs @@ -0,0 +1,24 @@ +// 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() { + ["Decrypt.Byte"] = DecryptByte, + ["DecryptLast.Byte"] = DecryptLastByte, + ["Encrypt.Byte"] = EncryptByte, + ["EncryptLast.Byte"] = EncryptLastByte, + ["InverseMixColumns.Byte"] = InverseMixColumnsByte, + ["KeygenAssist.Byte.5"] = KeygenAssistByte5, + }; + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesBinOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesBinOpTest.template new file mode 100644 index 0000000..3f08761 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesBinOpTest.template @@ -0,0 +1,374 @@ +// 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}() + { + var test = new SimpleBinaryOpTest__{Method}{RetBaseType}(); + + 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 SimpleBinaryOpTest__{Method}{RetBaseType} + { + 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(SimpleBinaryOpTest__{Method}{RetBaseType} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2); + + 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}[{InputSize}] {Input}; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[{KeySize}] {Key}; + 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 SimpleBinaryOpTest__{Method}{RetBaseType}() + { + + 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 SimpleBinaryOpTest__{Method}{RetBaseType}() + { + 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) + ); + + 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)) + ); + + 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)) + ); + + 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}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr) + }); + + 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}>) }) + .Invoke(null, new object[] { + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)) + }); + + 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}>) }) + .Invoke(null, new object[] { + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)), + {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar1, + _clsVar2 + ); + + 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); + + 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); + + 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); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleBinaryOpTest__{Method}{RetBaseType}(); + var result = {Isa}.{Method}(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2); + + 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); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(outArray, method); + } + + + private void ValidateResult({RetBaseType}[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + } + } + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {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/Shared/AesImmOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesImmOpTest.template new file mode 100644 index 0000000..87452cd --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesImmOpTest.template @@ -0,0 +1,362 @@ +// 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 ImmUnaryOpTest__{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 ImmUnaryOpTest__{Method}{RetBaseType}{Imm} + { + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario(ImmUnaryOpTest__{Method}{RetBaseType}{Imm} testClass) + { + var result = {Isa}.{Method}(_fld, {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}[] _data = new {Op1BaseType}[{InputSize}] {Input}; + private static {RetBaseType}[] _expectedRet = new {RetBaseType}[{ExpectedRetSize}] {ExpectedRet}; + + private static {Op1VectorType}<{Op1BaseType}> _clsVar; + + private {Op1VectorType}<{Op1BaseType}> _fld; + + private SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable; + + static ImmUnaryOpTest__{Method}{RetBaseType}{Imm}() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + } + + public ImmUnaryOpTest__{Method}{RetBaseType}{Imm}() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + + _dataTable = new SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data, 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.inArrayPtr), + {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.inArrayPtr)), + {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.inArrayPtr)), + {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(byte) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr), + (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(byte) }) + .Invoke(null, new object[] { + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)), + (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(byte) }) + .Invoke(null, new object[] { + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)), + (byte){Imm} + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar, + {Imm} + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr); + var result = {Isa}.{Method}(firstOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)); + var result = {Isa}.{Method}(firstOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)); + var result = {Isa}.{Method}(firstOp, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new ImmUnaryOpTest__{Method}{RetBaseType}{Imm}(); + var result = {Isa}.{Method}(test._fld, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld, {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._fld, {Imm}); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult({RetBaseType}[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + break; + } + } + + 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); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesUnOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesUnOpTest.template new file mode 100644 index 0000000..8679423 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AesUnOpTest.template @@ -0,0 +1,356 @@ +// 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}() + { + var test = new SimpleUnaryOpTest__{Method}{RetBaseType}(); + + 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 SimpleUnaryOpTest__{Method}{RetBaseType} + { + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + return testStruct; + } + + public void RunStructFldScenario(SimpleUnaryOpTest__{Method}{RetBaseType} testClass) + { + var result = {Isa}.{Method}(_fld); + + 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}[] _data = new {Op1BaseType}[{InputSize}] {Input}; + private static {RetBaseType}[] _expectedRet = new {RetBaseType}[{ExpectedRetSize}] {ExpectedRet}; + + private static {Op1VectorType}<{Op1BaseType}> _clsVar; + + private {Op1VectorType}<{Op1BaseType}> _fld; + + private SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable; + + static SimpleUnaryOpTest__{Method}{RetBaseType}() + { + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + } + + public SimpleUnaryOpTest__{Method}{RetBaseType}() + { + Succeeded = true; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + + _dataTable = new SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data, 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.inArrayPtr) + ); + + 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.inArrayPtr)) + ); + + 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.inArrayPtr)) + ); + + 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}>) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr) + }); + + 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}>) }) + .Invoke(null, new object[] { + {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)) + }); + + 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}>) }) + .Invoke(null, new object[] { + {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)) + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario)); + + var result = {Isa}.{Method}( + _clsVar + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr); + var result = {Isa}.{Method}(firstOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load)); + + var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)); + var result = {Isa}.{Method}(firstOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned)); + + var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)); + var result = {Isa}.{Method}(firstOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario)); + + var test = new SimpleUnaryOpTest__{Method}{RetBaseType}(); + var result = {Isa}.{Method}(test._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld); + + 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._fld); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + + private void ValidateResult(void* result, [CallerMemberName] string method = "") + { + + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(outArray, method); + } + + private void ValidateResult({RetBaseType}[] result, [CallerMemberName] string method = "") + { + for (int i = 0; i < result.Length; i++) + { + if (result[i] != _expectedRet[i] ) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {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/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx index ac70352..d0f34dc 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx @@ -862,6 +862,16 @@ private static readonly (string templateFileName, Dictionary tem ("ScalarUnOpTest.template", new Dictionary { ["Isa"] = "Bmi1", ["Method"] = "TrailingZeroCount", ["RetBaseType"] = "UInt64", ["Op1BaseType"] = "UInt64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateResult"] = "ulong expectedResult = 0; for (int index = 0; ((data >> index) & 1) == 0; index++) { expectedResult++; } isUnexpectedResult = (expectedResult != result);" }), }; +private static readonly (string templateFileName, Dictionary templateData)[] AesInputs = new [] +{ + ("AesBinOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "Decrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x8f, 0xc4, 0xfe, 0x76, 0x51, 0x4f, 0x4e, 0x04, 0xee, 0x39, 0xda, 0x81, 0xa3, 0xcf, 0x7e, 0xb5}"}), + ("AesBinOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "DecryptLast", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x9e, 0xbf, 0x72, 0x90, 0x7d, 0xd5, 0xca, 0x36, 0x93, 0xa4, 0xa4, 0x1f, 0x98, 0xdd, 0x10, 0xf2}"}), + ("AesBinOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "Encrypt", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xed, 0x42, 0xc4, 0xdf, 0x57, 0x0e, 0xab, 0x16, 0x33, 0x43, 0x50, 0x84, 0x18, 0xee, 0xe4, 0x28}"}), + ("AesBinOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "EncryptLast", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["KeySize"] = "16", ["Key"] = "{0xff, 0xdd, 0xbb, 0x99, 0x77, 0x55, 0x33, 0x11, 0xee, 0xcc, 0xaa, 0x88, 0x66, 0x44, 0x22, 0x00}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x20, 0xb3, 0x7a, 0x5d, 0xf2, 0x7d, 0xdd, 0xb6, 0xf8, 0x60, 0xc8, 0xf4, 0x8c, 0xf9, 0x04, 0x4b}"}), + ("AesUnOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "InverseMixColumns", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0xa0, 0x0a, 0xe4, 0x4e, 0x28, 0x82, 0x6c, 0xc6, 0x55, 0x00, 0x77, 0x22, 0x11, 0x44, 0x33, 0x66}"}), + ("AesImmOpTest.template", new Dictionary { ["Isa"] = "Aes", ["LoadIsa"] = "Aes", ["Method"] = "KeygenAssist", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["InputSize"] = "16", ["Input"] = "{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}", ["ExpectedRetSize"] = "16", ["ExpectedRet"] = "{0x85, 0x6e, 0x26, 0x7c, 0x6b, 0x26, 0x7c, 0x85, 0xea, 0xac, 0xee, 0xc4, 0xa9, 0xee, 0xc4, 0xea}"}), +}; + private 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® @@ -991,7 +1001,8 @@ private static bool isImmTemplate(string name) return name == "ImmUnOpTest.template" || name == "InsertScalarTest.template" || name == "ExtractScalarTest.template" || name == "InsertVector128Test.template" || name == "ExtractVector128Test.template" || name == "InsertLoadTest.template" || - name == "ExtractStoreTest.template" || name == "ImmBinOpTest.template"; + name == "ExtractStoreTest.template" || name == "ImmBinOpTest.template" || + name == "AesImmOpTest.template"; } private static void ProcessInput(StreamWriter testListFile, string groupName, (string templateFileName, Dictionary templateData) input) @@ -1047,3 +1058,4 @@ ProcessInputs("Fma_Vector128", Fma_Vector128Inputs); ProcessInputs("Fma_Vector256", Fma_Vector256Inputs); ProcessInputs("Bmi1", Bmi1Inputs); ProcessInputs("Bmi2", Bmi2Inputs); +ProcessInputs("Aes", AesInputs); -- 2.7.4