a81d9928e5a866e53c5f84720d0f6be1dd200501
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Sse41 / Insert.Single.16.cs
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.
4
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  ******************************************************************************/
11
12 using System;
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;
19
20 namespace JIT.HardwareIntrinsics.X86
21 {
22     public static partial class Program
23     {
24         private static void InsertSingle16()
25         {
26             var test = new InsertVector128Test__InsertSingle16();
27
28             if (test.IsSupported)
29             {
30                 // Validates basic functionality works, using Unsafe.Read
31                 test.RunBasicScenario_UnsafeRead();
32
33                 if (Sse.IsSupported)
34                 {
35                     // Validates basic functionality works, using Load
36                     test.RunBasicScenario_Load();
37
38                     // Validates basic functionality works, using LoadAligned
39                     test.RunBasicScenario_LoadAligned();
40                 }
41
42                 // Validates calling via reflection works, using Unsafe.Read
43                 test.RunReflectionScenario_UnsafeRead();
44
45                 if (Sse.IsSupported)
46                 {
47                     // Validates calling via reflection works, using Load
48                     test.RunReflectionScenario_Load();
49
50                     // Validates calling via reflection works, using LoadAligned
51                     test.RunReflectionScenario_LoadAligned();
52                 }
53
54                 // Validates passing a static member works
55                 test.RunClsVarScenario();
56
57                 // Validates passing a local works, using Unsafe.Read
58                 test.RunLclVarScenario_UnsafeRead();
59
60                 if (Sse.IsSupported)
61                 {
62                     // Validates passing a local works, using Load
63                     test.RunLclVarScenario_Load();
64
65                     // Validates passing a local works, using LoadAligned
66                     test.RunLclVarScenario_LoadAligned();
67                 }
68
69                 // Validates passing the field of a local class works
70                 test.RunClassLclFldScenario();
71
72                 // Validates passing an instance member of a class works
73                 test.RunClassFldScenario();
74
75                 // Validates passing the field of a local struct works
76                 test.RunStructLclFldScenario();
77
78                 // Validates passing an instance member of a struct works
79                 test.RunStructFldScenario();
80             }
81             else
82             {
83                 // Validates we throw on unsupported hardware
84                 test.RunUnsupportedScenario();
85             }
86
87             if (!test.Succeeded)
88             {
89                 throw new Exception("One or more scenarios did not complete as expected.");
90             }
91         }
92     }
93
94     public sealed unsafe class InsertVector128Test__InsertSingle16
95     {
96         private struct TestStruct
97         {
98             public Vector128<Single> _fld1;
99             public Vector128<Single> _fld2;
100
101             public static TestStruct Create()
102             {
103                 var testStruct = new TestStruct();
104                 var random = new Random();
105
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>>());
110
111                 return testStruct;
112             }
113
114             public void RunStructFldScenario(InsertVector128Test__InsertSingle16 testClass)
115             {
116                 var result = Sse41.Insert(_fld1, _fld2, 16);
117
118                 Unsafe.Write(testClass._dataTable.outArrayPtr, result);
119                 testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
120             }
121         }
122
123         private static readonly int LargestVectorSize = 16;
124
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);
128
129         private static Single[] _data1 = new Single[Op1ElementCount];
130         private static Single[] _data2 = new Single[Op2ElementCount];
131
132         private static Vector128<Single> _clsVar1;
133         private static Vector128<Single> _clsVar2;
134
135         private Vector128<Single> _fld1;
136         private Vector128<Single> _fld2;
137
138         private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
139
140         static InsertVector128Test__InsertSingle16()
141         {
142             var random = new Random();
143
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>>());
148         }
149
150         public InsertVector128Test__InsertSingle16()
151         {
152             Succeeded = true;
153
154             var random = new Random();
155
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>>());
160
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);
164         }
165
166         public bool IsSupported => Sse41.IsSupported;
167
168         public bool Succeeded { get; set; }
169
170         public void RunBasicScenario_UnsafeRead()
171         {
172             var result = Sse41.Insert(
173                 Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr),
174                 Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
175                 16
176             );
177
178             Unsafe.Write(_dataTable.outArrayPtr, result);
179             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
180         }
181
182         public void RunBasicScenario_Load()
183         {
184             var result = Sse41.Insert(
185                 Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr)),
186                 LoadVector128((Single*)(_dataTable.inArray2Ptr)),
187                 16
188             );
189
190             Unsafe.Write(_dataTable.outArrayPtr, result);
191             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
192         }
193
194         public void RunBasicScenario_LoadAligned()
195         {
196             var result = Sse41.Insert(
197                 Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr)),
198                 LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
199                 16
200             );
201
202             Unsafe.Write(_dataTable.outArrayPtr, result);
203             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
204         }
205
206         public void RunReflectionScenario_UnsafeRead()
207         {
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),
212                                         (byte)16
213                                      });
214
215             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
216             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
217         }
218
219         public void RunReflectionScenario_Load()
220         {
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)),
225                                         (byte)16
226                                      });
227
228             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
229             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
230         }
231
232         public void RunReflectionScenario_LoadAligned()
233         {
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)),
238                                         (byte)16
239                                      });
240
241             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
242             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
243         }
244
245         public void RunClsVarScenario()
246         {
247             var result = Sse41.Insert(
248                 _clsVar1,
249                 _clsVar2,
250                 16
251             );
252
253             Unsafe.Write(_dataTable.outArrayPtr, result);
254             ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
255         }
256
257         public void RunLclVarScenario_UnsafeRead()
258         {
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);
262
263             Unsafe.Write(_dataTable.outArrayPtr, result);
264             ValidateResult(left, right, _dataTable.outArrayPtr);
265         }
266
267         public void RunLclVarScenario_Load()
268         {
269             var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
270             var right = LoadVector128((Single*)(_dataTable.inArray2Ptr));
271             var result = Sse41.Insert(left, right, 16);
272
273             Unsafe.Write(_dataTable.outArrayPtr, result);
274             ValidateResult(left, right, _dataTable.outArrayPtr);
275         }
276
277         public void RunLclVarScenario_LoadAligned()
278         {
279             var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
280             var right = LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
281             var result = Sse41.Insert(left, right, 16);
282
283             Unsafe.Write(_dataTable.outArrayPtr, result);
284             ValidateResult(left, right, _dataTable.outArrayPtr);
285         }
286
287         public void RunClassLclFldScenario()
288         {
289             var test = new InsertVector128Test__InsertSingle16();
290             var result = Sse41.Insert(test._fld1, test._fld2, 16);
291
292             Unsafe.Write(_dataTable.outArrayPtr, result);
293             ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
294         }
295
296         public void RunClassFldScenario()
297         {
298             var result = Sse41.Insert(_fld1, _fld2, 16);
299
300             Unsafe.Write(_dataTable.outArrayPtr, result);
301             ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
302         }
303
304         public void RunStructLclFldScenario()
305         {
306             var test = TestStruct.Create();
307             var result = Sse41.Insert(test._fld1, test._fld2, 16);
308
309             Unsafe.Write(_dataTable.outArrayPtr, result);
310             ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
311         }
312
313         public void RunStructFldScenario()
314         {
315             var test = TestStruct.Create();
316             test.RunStructFldScenario(this);
317         }
318
319         public void RunUnsupportedScenario()
320         {
321             Succeeded = false;
322
323             try
324             {
325                 RunBasicScenario_UnsafeRead();
326             }
327             catch (PlatformNotSupportedException)
328             {
329                 Succeeded = true;
330             }
331         }
332
333         private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
334         {
335             Single[] inArray1 = new Single[Op1ElementCount];
336             Single[] inArray2 = new Single[Op2ElementCount];
337             Single[] outArray = new Single[RetElementCount];
338
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>>());
342
343             ValidateResult(inArray1, inArray2, outArray, method);
344         }
345
346         private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
347         {
348             Single[] inArray1 = new Single[Op1ElementCount];
349             Single[] inArray2 = new Single[Op2ElementCount];
350             Single[] outArray = new Single[RetElementCount];
351
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>>());
355
356             ValidateResult(inArray1, inArray2, outArray, method);
357         }
358
359         private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
360         {
361             if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(left[0]))
362             {
363                 Succeeded = false;
364             }
365             else
366             {
367                 for (var i = 1; i < RetElementCount; i++)
368                 {
369                     if (i == 1 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(right[0]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i]))
370                     {
371                         Succeeded = false;
372                         break;
373                     }
374                 }
375             }
376
377             if (!Succeeded)
378             {
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)})");
383                 Console.WriteLine();
384             }
385         }
386     }
387 }