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