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;
17 using static System.Runtime.Intrinsics.X86.Sse;
18 using static System.Runtime.Intrinsics.X86.Sse2;
20 namespace JIT.HardwareIntrinsics.X86
22 public static partial class Program
24 private static void InsertSingle16()
26 var test = new InsertVector128Test__InsertSingle16();
30 // Validates basic functionality works, using Unsafe.Read
31 test.RunBasicScenario_UnsafeRead();
35 // Validates basic functionality works, using Load
36 test.RunBasicScenario_Load();
38 // Validates basic functionality works, using LoadAligned
39 test.RunBasicScenario_LoadAligned();
42 // Validates calling via reflection works, using Unsafe.Read
43 test.RunReflectionScenario_UnsafeRead();
47 // Validates calling via reflection works, using Load
48 test.RunReflectionScenario_Load();
50 // Validates calling via reflection works, using LoadAligned
51 test.RunReflectionScenario_LoadAligned();
54 // Validates passing a static member works
55 test.RunClsVarScenario();
57 // Validates passing a local works, using Unsafe.Read
58 test.RunLclVarScenario_UnsafeRead();
62 // Validates passing a local works, using Load
63 test.RunLclVarScenario_Load();
65 // Validates passing a local works, using LoadAligned
66 test.RunLclVarScenario_LoadAligned();
69 // Validates passing the field of a local class works
70 test.RunClassLclFldScenario();
72 // Validates passing an instance member of a class works
73 test.RunClassFldScenario();
75 // Validates passing the field of a local struct works
76 test.RunStructLclFldScenario();
78 // Validates passing an instance member of a struct works
79 test.RunStructFldScenario();
83 // Validates we throw on unsupported hardware
84 test.RunUnsupportedScenario();
89 throw new Exception("One or more scenarios did not complete as expected.");
94 public sealed unsafe class InsertVector128Test__InsertSingle16
96 private struct TestStruct
98 public Vector128<Single> _fld1;
99 public Vector128<Single> _fld2;
101 public static TestStruct Create()
103 var testStruct = new TestStruct();
104 var random = new Random();
106 for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
107 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
108 for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
109 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
114 public void RunStructFldScenario(InsertVector128Test__InsertSingle16 testClass)
116 var result = Sse41.Insert(_fld1, _fld2, 16);
118 Unsafe.Write(testClass._dataTable.outArrayPtr, result);
119 testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
123 private static readonly int LargestVectorSize = 16;
125 private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
126 private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
127 private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
129 private static Single[] _data1 = new Single[Op1ElementCount];
130 private static Single[] _data2 = new Single[Op2ElementCount];
132 private static Vector128<Single> _clsVar1;
133 private static Vector128<Single> _clsVar2;
135 private Vector128<Single> _fld1;
136 private Vector128<Single> _fld2;
138 private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
140 static InsertVector128Test__InsertSingle16()
142 var random = new Random();
144 for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
145 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
146 for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
147 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
150 public InsertVector128Test__InsertSingle16()
154 var random = new Random();
156 for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
157 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
158 for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
159 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
161 for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
162 for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
163 _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
166 public bool IsSupported => Sse41.IsSupported;
168 public bool Succeeded { get; set; }
170 public void RunBasicScenario_UnsafeRead()
172 var result = Sse41.Insert(
173 Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr),
174 Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
178 Unsafe.Write(_dataTable.outArrayPtr, result);
179 ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
182 public void RunBasicScenario_Load()
184 var result = Sse41.Insert(
185 Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr)),
186 LoadVector128((Single*)(_dataTable.inArray2Ptr)),
190 Unsafe.Write(_dataTable.outArrayPtr, result);
191 ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
194 public void RunBasicScenario_LoadAligned()
196 var result = Sse41.Insert(
197 Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr)),
198 LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
202 Unsafe.Write(_dataTable.outArrayPtr, result);
203 ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
206 public void RunReflectionScenario_UnsafeRead()
208 var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Vector128<Single>), typeof(byte) })
209 .Invoke(null, new object[] {
210 Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr),
211 Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
215 Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
216 ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
219 public void RunReflectionScenario_Load()
221 var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Vector128<Single>), typeof(byte) })
222 .Invoke(null, new object[] {
223 Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr)),
224 LoadVector128((Single*)(_dataTable.inArray2Ptr)),
228 Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
229 ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
232 public void RunReflectionScenario_LoadAligned()
234 var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Single>), typeof(Vector128<Single>), typeof(byte) })
235 .Invoke(null, new object[] {
236 Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr)),
237 LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
241 Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
242 ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
245 public void RunClsVarScenario()
247 var result = Sse41.Insert(
253 Unsafe.Write(_dataTable.outArrayPtr, result);
254 ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
257 public void RunLclVarScenario_UnsafeRead()
259 var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
260 var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
261 var result = Sse41.Insert(left, right, 16);
263 Unsafe.Write(_dataTable.outArrayPtr, result);
264 ValidateResult(left, right, _dataTable.outArrayPtr);
267 public void RunLclVarScenario_Load()
269 var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
270 var right = LoadVector128((Single*)(_dataTable.inArray2Ptr));
271 var result = Sse41.Insert(left, right, 16);
273 Unsafe.Write(_dataTable.outArrayPtr, result);
274 ValidateResult(left, right, _dataTable.outArrayPtr);
277 public void RunLclVarScenario_LoadAligned()
279 var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
280 var right = LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
281 var result = Sse41.Insert(left, right, 16);
283 Unsafe.Write(_dataTable.outArrayPtr, result);
284 ValidateResult(left, right, _dataTable.outArrayPtr);
287 public void RunClassLclFldScenario()
289 var test = new InsertVector128Test__InsertSingle16();
290 var result = Sse41.Insert(test._fld1, test._fld2, 16);
292 Unsafe.Write(_dataTable.outArrayPtr, result);
293 ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
296 public void RunClassFldScenario()
298 var result = Sse41.Insert(_fld1, _fld2, 16);
300 Unsafe.Write(_dataTable.outArrayPtr, result);
301 ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
304 public void RunStructLclFldScenario()
306 var test = TestStruct.Create();
307 var result = Sse41.Insert(test._fld1, test._fld2, 16);
309 Unsafe.Write(_dataTable.outArrayPtr, result);
310 ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
313 public void RunStructFldScenario()
315 var test = TestStruct.Create();
316 test.RunStructFldScenario(this);
319 public void RunUnsupportedScenario()
325 RunBasicScenario_UnsafeRead();
327 catch (PlatformNotSupportedException)
333 private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
335 Single[] inArray1 = new Single[Op1ElementCount];
336 Single[] inArray2 = new Single[Op2ElementCount];
337 Single[] outArray = new Single[RetElementCount];
339 Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
340 Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
341 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
343 ValidateResult(inArray1, inArray2, outArray, method);
346 private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
348 Single[] inArray1 = new Single[Op1ElementCount];
349 Single[] inArray2 = new Single[Op2ElementCount];
350 Single[] outArray = new Single[RetElementCount];
352 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
353 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
354 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
356 ValidateResult(inArray1, inArray2, outArray, method);
359 private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
361 if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(left[0]))
367 for (var i = 1; i < RetElementCount; i++)
369 if (i == 1 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(right[0]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i]))
379 Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Single>(Vector128<Single>, Vector128<Single>.16): {method} failed:");
380 Console.WriteLine($" left: ({string.Join(", ", left)})");
381 Console.WriteLine($" right: ({string.Join(", ", right)})");
382 Console.WriteLine($" result: ({string.Join(", ", result)})");