Merge pull request #18504 from mikedn/comp-small
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Sse41 / Insert.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.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 InsertByte1()
23         {
24             var test = new SimpleUnaryOpTest__InsertByte1();
25
26             if (test.IsSupported)
27             {
28                 // Validates basic functionality works, using Unsafe.Read
29                 test.RunBasicScenario_UnsafeRead();
30
31                 if (Sse2.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 (Sse2.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 (Sse2.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__InsertByte1
87     {
88         private static readonly int LargestVectorSize = 16;
89
90         private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
91         private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
92
93         private static Byte[] _data = new Byte[Op1ElementCount];
94
95         private static Vector128<Byte> _clsVar;
96
97         private Vector128<Byte> _fld;
98
99         private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
100
101         static SimpleUnaryOpTest__InsertByte1()
102         {
103             var random = new Random();
104
105             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
106             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
107         }
108
109         public SimpleUnaryOpTest__InsertByte1()
110         {
111             Succeeded = true;
112
113             var random = new Random();
114
115             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
116             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
117
118             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
119             _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], LargestVectorSize);
120         }
121
122         public bool IsSupported => Sse41.IsSupported && (Environment.Is64BitProcess || ((typeof(Byte) != typeof(long)) && (typeof(Byte) != typeof(ulong))));
123
124         public bool Succeeded { get; set; }
125
126         public void RunBasicScenario_UnsafeRead()
127         {
128             var result = Sse41.Insert(
129                 Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr),
130                 (byte)2,
131                 1
132             );
133
134             Unsafe.Write(_dataTable.outArrayPtr, result);
135             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
136         }
137
138         public void RunBasicScenario_Load()
139         {
140             var result = Sse41.Insert(
141                 Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)),
142                 (byte)2,
143                 1
144             );
145
146             Unsafe.Write(_dataTable.outArrayPtr, result);
147             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
148         }
149
150         public void RunBasicScenario_LoadAligned()
151         {
152             var result = Sse41.Insert(
153                 Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)),
154                 (byte)2,
155                 1
156             );
157
158             Unsafe.Write(_dataTable.outArrayPtr, result);
159             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
160         }
161
162         public void RunReflectionScenario_UnsafeRead()
163         {
164             var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Byte>), typeof(Byte), typeof(byte) })
165                                      .Invoke(null, new object[] {
166                                         Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr),
167                                         (byte)2,
168                                         (byte)1
169                                      });
170
171             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
172             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
173         }
174
175         public void RunReflectionScenario_Load()
176         {
177             var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Byte>), typeof(Byte), typeof(byte) })
178                                      .Invoke(null, new object[] {
179                                         Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr)),
180                                         (byte)2,
181                                         (byte)1
182                                      });
183
184             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
185             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
186         }
187
188         public void RunReflectionScenario_LoadAligned()
189         {
190             var result = typeof(Sse41).GetMethod(nameof(Sse41.Insert), new Type[] { typeof(Vector128<Byte>), typeof(Byte), typeof(byte) })
191                                      .Invoke(null, new object[] {
192                                         Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr)),
193                                         (byte)2,
194                                         (byte)1
195                                      });
196
197             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
198             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
199         }
200
201         public void RunClsVarScenario()
202         {
203             var result = Sse41.Insert(
204                 _clsVar,
205                 (byte)2,
206                 1
207             );
208
209             Unsafe.Write(_dataTable.outArrayPtr, result);
210             ValidateResult(_clsVar, _dataTable.outArrayPtr);
211         }
212
213         public void RunLclVarScenario_UnsafeRead()
214         {
215             var firstOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr);
216             var result = Sse41.Insert(firstOp, (byte)2, 1);
217
218             Unsafe.Write(_dataTable.outArrayPtr, result);
219             ValidateResult(firstOp, _dataTable.outArrayPtr);
220         }
221
222         public void RunLclVarScenario_Load()
223         {
224             var firstOp = Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr));
225             var result = Sse41.Insert(firstOp, (byte)2, 1);
226
227             Unsafe.Write(_dataTable.outArrayPtr, result);
228             ValidateResult(firstOp, _dataTable.outArrayPtr);
229         }
230
231         public void RunLclVarScenario_LoadAligned()
232         {
233             var firstOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr));
234             var result = Sse41.Insert(firstOp, (byte)2, 1);
235
236             Unsafe.Write(_dataTable.outArrayPtr, result);
237             ValidateResult(firstOp, _dataTable.outArrayPtr);
238         }
239
240         public void RunLclFldScenario()
241         {
242             var test = new SimpleUnaryOpTest__InsertByte1();
243             var result = Sse41.Insert(test._fld, (byte)2, 1);
244
245             Unsafe.Write(_dataTable.outArrayPtr, result);
246             ValidateResult(test._fld, _dataTable.outArrayPtr);
247         }
248
249         public void RunFldScenario()
250         {
251             var result = Sse41.Insert(_fld, (byte)2, 1);
252
253             Unsafe.Write(_dataTable.outArrayPtr, result);
254             ValidateResult(_fld, _dataTable.outArrayPtr);
255         }
256
257         public void RunUnsupportedScenario()
258         {
259             Succeeded = false;
260
261             try
262             {
263                 RunBasicScenario_UnsafeRead();
264             }
265             catch (PlatformNotSupportedException)
266             {
267                 Succeeded = true;
268             }
269         }
270
271         private void ValidateResult(Vector128<Byte> firstOp, void* result, [CallerMemberName] string method = "")
272         {
273             Byte[] inArray = new Byte[Op1ElementCount];
274             Byte[] outArray = new Byte[RetElementCount];
275
276             Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), firstOp);
277             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
278
279             ValidateResult(inArray, outArray, method);
280         }
281
282         private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
283         {
284             Byte[] inArray = new Byte[Op1ElementCount];
285             Byte[] outArray = new Byte[RetElementCount];
286
287             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Byte>>());
288             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
289
290             ValidateResult(inArray, outArray, method);
291         }
292
293         private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
294         {
295
296             for (var i = 0; i < RetElementCount; i++)
297             {
298                 if ((i == 1 ? result[i] != 2 : result[i] != firstOp[i]))
299                 {
300                     Succeeded = false;
301                     break;
302                 }
303             }
304
305             if (!Succeeded)
306             {
307                 Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.Insert)}<Byte>(Vector128<Byte><9>): {method} failed:");
308                 Console.WriteLine($"  firstOp: ({string.Join(", ", firstOp)})");
309                 Console.WriteLine($"   result: ({string.Join(", ", result)})");
310                 Console.WriteLine();
311             }
312         }
313     }
314 }