diff options
author | Tanner Gooding <tagoo@outlook.com> | 2018-01-27 15:41:53 -0800 |
---|---|---|
committer | Tanner Gooding <tagoo@outlook.com> | 2018-01-27 17:56:39 -0800 |
commit | e40fcdaa636400319ccf45c191668ee830424d32 (patch) | |
tree | e6c9d4ac0ee6521ac331aac72693a76b45664d62 /tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs | |
parent | ba7172f5f4ae71f492b9bb129d98d932f987e0c5 (diff) | |
download | coreclr-e40fcdaa636400319ccf45c191668ee830424d32.tar.gz coreclr-e40fcdaa636400319ccf45c191668ee830424d32.tar.bz2 coreclr-e40fcdaa636400319ccf45c191668ee830424d32.zip |
Updating several of the Sse HardwareIntrinsic tests to be generated from a template.
Diffstat (limited to 'tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs')
-rw-r--r-- | tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs new file mode 100644 index 0000000000..d3f149289d --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs @@ -0,0 +1,209 @@ +// 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.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 SubtractScalarSingle() + { + var test = new SimpleBinaryOpTest__SubtractScalarSingle(); + + if (test.IsSupported) + { + // Validates basic functionality works + test.RunBasicScenario(); + + // Validates calling via reflection works + test.RunReflectionScenario(); + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works + test.RunLclVarScenario(); + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + 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__SubtractScalarSingle + { + private const int VectorSize = 16; + private const int ElementCount = VectorSize / sizeof(Single); + + private static Single[] _data1 = new Single[ElementCount]; + private static Single[] _data2 = new Single[ElementCount]; + + private static Vector128<Single> _clsVar1; + private static Vector128<Single> _clsVar2; + + private Vector128<Single> _fld1; + private Vector128<Single> _fld2; + + private SimpleBinaryOpTest__DataTable<Single> _dataTable; + + static SimpleBinaryOpTest__SubtractScalarSingle() + { + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize); + } + + public SimpleBinaryOpTest__SubtractScalarSingle() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize); + + for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); } + _dataTable = new SimpleBinaryOpTest__DataTable<Single>(_data1, _data2, new Single[ElementCount]); + } + + public bool IsSupported => Sse.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario() + { + var result = Sse.SubtractScalar( + Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr), + Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr) + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunReflectionScenario() + { + var result = typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), new Type[] { typeof(Vector128<Single>), typeof(Vector128<Single>) }) + .Invoke(null, new object[] { + Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr), + Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr) + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result)); + ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray); + } + + public void RunClsVarScenario() + { + var result = Sse.SubtractScalar( + _clsVar1, + _clsVar2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray); + } + + public void RunLclVarScenario() + { + var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr); + var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr); + var result = Sse.SubtractScalar(left, right); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(left, right, _dataTable.outArray); + } + + public void RunLclFldScenario() + { + var test = new SimpleBinaryOpTest__SubtractScalarSingle(); + var result = Sse.SubtractScalar(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArray); + } + + public void RunFldScenario() + { + var result = Sse.SubtractScalar(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArray); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector128<Single> left, Vector128<Single> right, Single[] result, [CallerMemberName] string method = "") + { + Single[] inArray1 = new Single[ElementCount]; + Single[] inArray2 = new Single[ElementCount]; + + Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left); + Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right); + + ValidateResult(inArray1, inArray2, result, method); + } + + private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "") + { + if (BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])) + { + Succeeded = false; + } + else + { + for (var i = 1; i < left.Length; i++) + { + if (BitConverter.SingleToInt32Bits(left[i]) != BitConverter.SingleToInt32Bits(result[i])) + { + Succeeded = false; + break; + } + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.SubtractScalar)}<Single>: {method} failed:"); + Console.WriteLine($" left: ({string.Join(", ", left)})"); + Console.WriteLine($" right: ({string.Join(", ", right)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} |