69546c70a4a37949439ccb93e2f8016a85c702bd
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Avx / InsertVector128.Byte.1.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.Reflection;
14 using System.Linq;
15 using System.Runtime.CompilerServices;
16 using System.Runtime.InteropServices;
17 using System.Runtime.Intrinsics;
18 using System.Runtime.Intrinsics.X86;
19 using static System.Runtime.Intrinsics.X86.Sse2;
20
21 namespace JIT.HardwareIntrinsics.X86
22 {
23     public static partial class Program
24     {
25         private static void InsertVector128Byte1()
26         {
27             var test = new SimpleBinaryOpTest__InsertVector128Byte1();
28
29             if (test.IsSupported)
30             {
31                 // Validates basic functionality works, using Unsafe.Read
32                 test.RunBasicScenario_UnsafeRead();
33
34                 if (Avx.IsSupported)
35                 {
36                     // Validates basic functionality works, using Load
37                     test.RunBasicScenario_Load();
38
39                     // Validates basic functionality works, using LoadAligned
40                     test.RunBasicScenario_LoadAligned();
41                 }
42
43                 // Validates calling via reflection works, using Unsafe.Read
44                 test.RunReflectionScenario_UnsafeRead();
45
46                 if (Avx.IsSupported)
47                 {
48                     // Validates calling via reflection works, using Load
49                     test.RunReflectionScenario_Load();
50
51                     // Validates calling via reflection works, using LoadAligned
52                     test.RunReflectionScenario_LoadAligned();
53                 }
54
55                 // Validates passing a static member works
56                 test.RunClsVarScenario();
57
58                 // Validates passing a local works, using Unsafe.Read
59                 test.RunLclVarScenario_UnsafeRead();
60
61                 if (Avx.IsSupported)
62                 {
63                     // Validates passing a local works, using Load
64                     test.RunLclVarScenario_Load();
65
66                     // Validates passing a local works, using LoadAligned
67                     test.RunLclVarScenario_LoadAligned();
68                 }
69
70                 // Validates passing the field of a local works
71                 test.RunLclFldScenario();
72
73                 // Validates passing an instance member works
74                 test.RunFldScenario();
75             }
76             else
77             {
78                 // Validates we throw on unsupported hardware
79                 test.RunUnsupportedScenario();
80             }
81
82             if (!test.Succeeded)
83             {
84                 throw new Exception("One or more scenarios did not complete as expected.");
85             }
86         }
87     }
88
89     public sealed unsafe class SimpleBinaryOpTest__InsertVector128Byte1
90     {
91         private static readonly int LargestVectorSize = 32;
92
93         private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Byte>>() / sizeof(Byte);
94         private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
95         private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Byte>>() / sizeof(Byte);
96
97         private static Byte[] _data1 = new Byte[Op1ElementCount];
98         private static Byte[] _data2 = new Byte[Op2ElementCount];
99
100         private static Vector256<Byte> _clsVar1;
101         private static Vector128<Byte> _clsVar2;
102
103         private Vector256<Byte> _fld1;
104         private Vector128<Byte> _fld2;
105
106         private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
107
108         static SimpleBinaryOpTest__InsertVector128Byte1()
109         {
110             var random = new Random();
111
112             for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
113             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
114             for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
115             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
116         }
117
118         public SimpleBinaryOpTest__InsertVector128Byte1()
119         {
120             Succeeded = true;
121
122             var random = new Random();
123
124             for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
125             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
126             for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
127             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
128
129             for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
130             for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
131             _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
132         }
133
134         public bool IsSupported => Avx.IsSupported;
135
136         public bool Succeeded { get; set; }
137
138         public void RunBasicScenario_UnsafeRead()
139         {
140             var result = Avx.InsertVector128(
141                 Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
142                 Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
143                 1
144             );
145
146             Unsafe.Write(_dataTable.outArrayPtr, result);
147             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
148         }
149
150         public void RunBasicScenario_Load()
151         {
152             var result = Avx.InsertVector128(
153                 Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
154                 LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
155                 1
156             );
157
158             Unsafe.Write(_dataTable.outArrayPtr, result);
159             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
160         }
161
162         public void RunBasicScenario_LoadAligned()
163         {
164             var result = Avx.InsertVector128(
165                 Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
166                 LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
167                 1
168             );
169
170             Unsafe.Write(_dataTable.outArrayPtr, result);
171             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
172         }
173
174         public void RunReflectionScenario_UnsafeRead()
175         {
176             var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
177                                      .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
178                                      .MakeGenericMethod(new[] { typeof(Byte) })
179                                      .Invoke(null, new object[] {
180                                         Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
181                                         Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
182                                         (byte)1
183                                      });
184
185             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
186             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
187         }
188
189         public void RunReflectionScenario_Load()
190         {
191             var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
192                                      .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
193                                      .MakeGenericMethod(new[] { typeof(Byte) })
194                                      .Invoke(null, new object[] {
195                                         Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
196                                         LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
197                                         (byte)1
198                                      });
199
200             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
201             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
202         }
203
204         public void RunReflectionScenario_LoadAligned()
205         {
206             var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
207                                      .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
208                                      .MakeGenericMethod(new[] { typeof(Byte) })
209                                      .Invoke(null, new object[] {
210                                         Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
211                                         LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
212                                         (byte)1
213                                      });
214
215             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
216             ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
217         }
218
219         public void RunClsVarScenario()
220         {
221             var result = Avx.InsertVector128(
222                 _clsVar1,
223                 _clsVar2,
224                 1
225             );
226
227             Unsafe.Write(_dataTable.outArrayPtr, result);
228             ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
229         }
230
231         public void RunLclVarScenario_UnsafeRead()
232         {
233             var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
234             var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
235             var result = Avx.InsertVector128(left, right, 1);
236
237             Unsafe.Write(_dataTable.outArrayPtr, result);
238             ValidateResult(left, right, _dataTable.outArrayPtr);
239         }
240
241         public void RunLclVarScenario_Load()
242         {
243             var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
244             var right = LoadVector128((Byte*)(_dataTable.inArray2Ptr));
245             var result = Avx.InsertVector128(left, right, 1);
246
247             Unsafe.Write(_dataTable.outArrayPtr, result);
248             ValidateResult(left, right, _dataTable.outArrayPtr);
249         }
250
251         public void RunLclVarScenario_LoadAligned()
252         {
253             var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
254             var right = LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
255             var result = Avx.InsertVector128(left, right, 1);
256
257             Unsafe.Write(_dataTable.outArrayPtr, result);
258             ValidateResult(left, right, _dataTable.outArrayPtr);
259         }
260
261         public void RunLclFldScenario()
262         {
263             var test = new SimpleBinaryOpTest__InsertVector128Byte1();
264             var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
265
266             Unsafe.Write(_dataTable.outArrayPtr, result);
267             ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
268         }
269
270         public void RunFldScenario()
271         {
272             var result = Avx.InsertVector128(_fld1, _fld2, 1);
273
274             Unsafe.Write(_dataTable.outArrayPtr, result);
275             ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
276         }
277
278         public void RunUnsupportedScenario()
279         {
280             Succeeded = false;
281
282             try
283             {
284                 RunBasicScenario_UnsafeRead();
285             }
286             catch (PlatformNotSupportedException)
287             {
288                 Succeeded = true;
289             }
290         }
291
292         private void ValidateResult(Vector256<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
293         {
294             Byte[] inArray1 = new Byte[Op1ElementCount];
295             Byte[] inArray2 = new Byte[Op2ElementCount];
296             Byte[] outArray = new Byte[RetElementCount];
297
298             Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
299             Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
300             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
301
302             ValidateResult(inArray1, inArray2, outArray, method);
303         }
304
305         private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
306         {
307             Byte[] inArray1 = new Byte[Op1ElementCount];
308             Byte[] inArray2 = new Byte[Op2ElementCount];
309             Byte[] outArray = new Byte[RetElementCount];
310
311             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
312             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
313             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
314
315             ValidateResult(inArray1, inArray2, outArray, method);
316         }
317
318         private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
319         {
320             if (result[0] != left[0])
321             {
322                 Succeeded = false;
323             }
324             else
325             {
326                 for (var i = 1; i < RetElementCount; i++)
327                 {
328                     if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
329                     {
330                         Succeeded = false;
331                         break;
332                     }
333                 }
334             }
335
336             if (!Succeeded)
337             {
338                 Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {method} failed:");
339                 Console.WriteLine($"    left: ({string.Join(", ", left)})");
340                 Console.WriteLine($"   right: ({string.Join(", ", right)})");
341                 Console.WriteLine($"  result: ({string.Join(", ", result)})");
342                 Console.WriteLine();
343             }
344         }
345     }
346 }