summaryrefslogtreecommitdiff
path: root/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2018-01-27 15:41:53 -0800
committerTanner Gooding <tagoo@outlook.com>2018-01-27 17:56:39 -0800
commite40fcdaa636400319ccf45c191668ee830424d32 (patch)
treee6c9d4ac0ee6521ac331aac72693a76b45664d62 /tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs
parentba7172f5f4ae71f492b9bb129d98d932f987e0c5 (diff)
downloadcoreclr-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.cs209
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();
+ }
+ }
+ }
+}