1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 /******************************************************************************
6 * This file is auto-generated from a template file by the GenerateTests.csx *
7 * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
8 * changes, please update the corresponding template and run according to the *
9 * directions listed in the file. *
10 ******************************************************************************/
13 using System.Runtime.CompilerServices;
14 using System.Runtime.InteropServices;
15 using System.Runtime.Intrinsics;
16 using System.Runtime.Intrinsics.X86;
18 namespace JIT.HardwareIntrinsics.X86
20 public static partial class Program
22 private static void RoundToNearestIntegerDouble()
24 var test = new SimpleUnaryOpTest__RoundToNearestIntegerDouble();
28 // Validates basic functionality works, using Unsafe.Read
29 test.RunBasicScenario_UnsafeRead();
33 // Validates basic functionality works, using Load
34 test.RunBasicScenario_Load();
36 // Validates basic functionality works, using LoadAligned
37 test.RunBasicScenario_LoadAligned();
40 // Validates calling via reflection works, using Unsafe.Read
41 test.RunReflectionScenario_UnsafeRead();
45 // Validates calling via reflection works, using Load
46 test.RunReflectionScenario_Load();
48 // Validates calling via reflection works, using LoadAligned
49 test.RunReflectionScenario_LoadAligned();
52 // Validates passing a static member works
53 test.RunClsVarScenario();
55 // Validates passing a local works, using Unsafe.Read
56 test.RunLclVarScenario_UnsafeRead();
60 // Validates passing a local works, using Load
61 test.RunLclVarScenario_Load();
63 // Validates passing a local works, using LoadAligned
64 test.RunLclVarScenario_LoadAligned();
67 // Validates passing the field of a local class works
68 test.RunClassLclFldScenario();
70 // Validates passing an instance member of a class works
71 test.RunClassFldScenario();
73 // Validates passing the field of a local struct works
74 test.RunStructLclFldScenario();
76 // Validates passing an instance member of a struct works
77 test.RunStructFldScenario();
81 // Validates we throw on unsupported hardware
82 test.RunUnsupportedScenario();
87 throw new Exception("One or more scenarios did not complete as expected.");
92 public sealed unsafe class SimpleUnaryOpTest__RoundToNearestIntegerDouble
94 private struct TestStruct
96 public Vector128<Double> _fld;
98 public static TestStruct Create()
100 var testStruct = new TestStruct();
101 var random = new Random();
103 for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
104 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
109 public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNearestIntegerDouble testClass)
111 var result = Sse41.RoundToNearestInteger(_fld);
113 Unsafe.Write(testClass._dataTable.outArrayPtr, result);
114 testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
118 private static readonly int LargestVectorSize = 16;
120 private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
121 private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
123 private static Double[] _data = new Double[Op1ElementCount];
125 private static Vector128<Double> _clsVar;
127 private Vector128<Double> _fld;
129 private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
131 static SimpleUnaryOpTest__RoundToNearestIntegerDouble()
133 var random = new Random();
135 for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
136 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
139 public SimpleUnaryOpTest__RoundToNearestIntegerDouble()
143 var random = new Random();
145 for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
146 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
148 for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
149 _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
152 public bool IsSupported => Sse41.IsSupported;
154 public bool Succeeded { get; set; }
156 public void RunBasicScenario_UnsafeRead()
158 var result = Sse41.RoundToNearestInteger(
159 Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
162 Unsafe.Write(_dataTable.outArrayPtr, result);
163 ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
166 public void RunBasicScenario_Load()
168 var result = Sse41.RoundToNearestInteger(
169 Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
172 Unsafe.Write(_dataTable.outArrayPtr, result);
173 ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
176 public void RunBasicScenario_LoadAligned()
178 var result = Sse41.RoundToNearestInteger(
179 Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
182 Unsafe.Write(_dataTable.outArrayPtr, result);
183 ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
186 public void RunReflectionScenario_UnsafeRead()
188 var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Double>) })
189 .Invoke(null, new object[] {
190 Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
193 Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
194 ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
197 public void RunReflectionScenario_Load()
199 var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Double>) })
200 .Invoke(null, new object[] {
201 Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
204 Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
205 ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
208 public void RunReflectionScenario_LoadAligned()
210 var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Double>) })
211 .Invoke(null, new object[] {
212 Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
215 Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
216 ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
219 public void RunClsVarScenario()
221 var result = Sse41.RoundToNearestInteger(
225 Unsafe.Write(_dataTable.outArrayPtr, result);
226 ValidateResult(_clsVar, _dataTable.outArrayPtr);
229 public void RunLclVarScenario_UnsafeRead()
231 var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
232 var result = Sse41.RoundToNearestInteger(firstOp);
234 Unsafe.Write(_dataTable.outArrayPtr, result);
235 ValidateResult(firstOp, _dataTable.outArrayPtr);
238 public void RunLclVarScenario_Load()
240 var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
241 var result = Sse41.RoundToNearestInteger(firstOp);
243 Unsafe.Write(_dataTable.outArrayPtr, result);
244 ValidateResult(firstOp, _dataTable.outArrayPtr);
247 public void RunLclVarScenario_LoadAligned()
249 var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
250 var result = Sse41.RoundToNearestInteger(firstOp);
252 Unsafe.Write(_dataTable.outArrayPtr, result);
253 ValidateResult(firstOp, _dataTable.outArrayPtr);
256 public void RunClassLclFldScenario()
258 var test = new SimpleUnaryOpTest__RoundToNearestIntegerDouble();
259 var result = Sse41.RoundToNearestInteger(test._fld);
261 Unsafe.Write(_dataTable.outArrayPtr, result);
262 ValidateResult(test._fld, _dataTable.outArrayPtr);
265 public void RunClassFldScenario()
267 var result = Sse41.RoundToNearestInteger(_fld);
269 Unsafe.Write(_dataTable.outArrayPtr, result);
270 ValidateResult(_fld, _dataTable.outArrayPtr);
273 public void RunStructLclFldScenario()
275 var test = TestStruct.Create();
276 var result = Sse41.RoundToNearestInteger(test._fld);
278 Unsafe.Write(_dataTable.outArrayPtr, result);
279 ValidateResult(test._fld, _dataTable.outArrayPtr);
282 public void RunStructFldScenario()
284 var test = TestStruct.Create();
285 test.RunStructFldScenario(this);
288 public void RunUnsupportedScenario()
294 RunBasicScenario_UnsafeRead();
296 catch (PlatformNotSupportedException)
302 private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
304 Double[] inArray = new Double[Op1ElementCount];
305 Double[] outArray = new Double[RetElementCount];
307 Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
308 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
310 ValidateResult(inArray, outArray, method);
313 private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
315 Double[] inArray = new Double[Op1ElementCount];
316 Double[] outArray = new Double[RetElementCount];
318 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
319 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
321 ValidateResult(inArray, outArray, method);
324 private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
326 if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0], MidpointRounding.AwayFromZero)))
332 for (var i = 1; i < RetElementCount; i++)
334 if (BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i], MidpointRounding.AwayFromZero)))
344 Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.RoundToNearestInteger)}<Double>(Vector128<Double>): {method} failed:");
345 Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
346 Console.WriteLine($" result: ({string.Join(", ", result)})");