Merge pull request #16133 from eerhardt/AddVectorToCoreLib
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Sse / CompareOrdered.Single.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 CompareOrderedSingle()
23         {
24             var test = new SimpleBinaryOpTest__CompareOrderedSingle();
25
26             if (test.IsSupported)
27             {
28                 // Validates basic functionality works
29                 test.RunBasicScenario();
30
31                 // Validates calling via reflection works
32                 test.RunReflectionScenario();
33
34                 // Validates passing a static member works
35                 test.RunClsVarScenario();
36
37                 // Validates passing a local works
38                 test.RunLclVarScenario();
39
40                 // Validates passing the field of a local works
41                 test.RunLclFldScenario();
42
43                 // Validates passing an instance member works
44                 test.RunFldScenario();
45             }
46             else
47             {
48                 // Validates we throw on unsupported hardware
49                 test.RunUnsupportedScenario();
50             }
51
52             if (!test.Succeeded)
53             {
54                 throw new Exception("One or more scenarios did not complete as expected.");
55             }
56         }
57     }
58
59     public sealed unsafe class SimpleBinaryOpTest__CompareOrderedSingle
60     {
61         private const int VectorSize = 16;
62         private const int ElementCount = VectorSize / sizeof(Single);
63
64         private static Single[] _data1 = new Single[ElementCount];
65         private static Single[] _data2 = new Single[ElementCount];
66
67         private static Vector128<Single> _clsVar1;
68         private static Vector128<Single> _clsVar2;
69
70         private Vector128<Single> _fld1;
71         private Vector128<Single> _fld2;
72
73         private SimpleBinaryOpTest__DataTable<Single> _dataTable;
74
75         static SimpleBinaryOpTest__CompareOrderedSingle()
76         {
77             var random = new Random();
78
79             for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); }
80             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
81             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
82         }
83
84         public SimpleBinaryOpTest__CompareOrderedSingle()
85         {
86             Succeeded = true;
87
88             var random = new Random();
89
90             for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); }
91             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
92             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
93
94             for (var i = 0; i < ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); _data2[i] = (float)(random.NextDouble()); }
95             _dataTable = new SimpleBinaryOpTest__DataTable<Single>(_data1, _data2, new Single[ElementCount]);
96         }
97
98         public bool IsSupported => Sse.IsSupported;
99
100         public bool Succeeded { get; set; }
101
102         public void RunBasicScenario()
103         {
104             var result = Sse.CompareOrdered(
105                 Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr),
106                 Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr)
107             );
108
109             Unsafe.Write(_dataTable.outArrayPtr, result);
110             ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
111         }
112
113         public void RunReflectionScenario()
114         {
115             var result = typeof(Sse).GetMethod(nameof(Sse.CompareOrdered), new Type[] { typeof(Vector128<Single>), typeof(Vector128<Single>) })
116                                      .Invoke(null, new object[] {
117                                         Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr),
118                                         Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr)
119                                      });
120
121             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
122             ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
123         }
124
125         public void RunClsVarScenario()
126         {
127             var result = Sse.CompareOrdered(
128                 _clsVar1,
129                 _clsVar2
130             );
131
132             Unsafe.Write(_dataTable.outArrayPtr, result);
133             ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
134         }
135
136         public void RunLclVarScenario()
137         {
138             var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
139             var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
140             var result = Sse.CompareOrdered(left, right);
141
142             Unsafe.Write(_dataTable.outArrayPtr, result);
143             ValidateResult(left, right, _dataTable.outArray);
144         }
145
146         public void RunLclFldScenario()
147         {
148             var test = new SimpleBinaryOpTest__CompareOrderedSingle();
149             var result = Sse.CompareOrdered(test._fld1, test._fld2);
150
151             Unsafe.Write(_dataTable.outArrayPtr, result);
152             ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
153         }
154
155         public void RunFldScenario()
156         {
157             var result = Sse.CompareOrdered(_fld1, _fld2);
158
159             Unsafe.Write(_dataTable.outArrayPtr, result);
160             ValidateResult(_fld1, _fld2, _dataTable.outArray);
161         }
162
163         public void RunUnsupportedScenario()
164         {
165             Succeeded = false;
166
167             try
168             {
169                 RunBasicScenario();
170             }
171             catch (PlatformNotSupportedException)
172             {
173                 Succeeded = true;
174             }
175         }
176
177         private void ValidateResult(Vector128<Single> left, Vector128<Single> right, Single[] result, [CallerMemberName] string method = "")
178         {
179             Single[] inArray1 = new Single[ElementCount];
180             Single[] inArray2 = new Single[ElementCount];
181
182             Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
183             Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
184
185             ValidateResult(inArray1, inArray2, result, method);
186         }
187
188         private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
189         {
190             if (BitConverter.SingleToInt32Bits(result[0]) != ((!float.IsNaN(left[0]) && !float.IsNaN(right[0])) ? -1 : 0))
191             {
192                 Succeeded = false;
193             }
194             else
195             {
196                 for (var i = 1; i < left.Length; i++)
197                 {
198                     if (BitConverter.SingleToInt32Bits(result[i]) != ((!float.IsNaN(left[i]) && !float.IsNaN(right[i])) ? -1 : 0))
199                     {
200                         Succeeded = false;
201                         break;
202                     }
203                 }
204             }
205
206             if (!Succeeded)
207             {
208                 Console.WriteLine($"{nameof(Sse)}.{nameof(Sse.CompareOrdered)}<Single>: {method} failed:");
209                 Console.WriteLine($"    left: ({string.Join(", ", left)})");
210                 Console.WriteLine($"   right: ({string.Join(", ", right)})");
211                 Console.WriteLine($"  result: ({string.Join(", ", result)})");
212                 Console.WriteLine();
213             }
214         }
215     }
216 }