[netcore] Implement missing Bmi1/Bmi2 intrinsics (#16919)
[mono-project.git] / mono / mini / basic-math.cs
blob1ffdeeef11a1ba97c70c676c4a4c8b0a0916a0d5
1 using System;
2 using System.Reflection;
4 /*
5 * Regression tests for the mono JIT.
7 * Each test needs to be of the form:
9 * public static int test_<result>_<name> ();
11 * where <result> is an integer (the value that needs to be returned by
12 * the method to make it pass.
13 * <name> is a user-displayed name used to identify the test.
15 * The tests can be driven in two ways:
16 * *) running the program directly: Main() uses reflection to find and invoke
17 * the test methods (this is useful mostly to check that the tests are correct)
18 * *) with the --regression switch of the jit (this is the preferred way since
19 * all the tests will be run with optimizations on and off)
21 * The reflection logic could be moved to a .dll since we need at least another
22 * regression test file written in IL code to have better control on how
23 * the IL code looks.
26 #if __MOBILE__
27 class MathTests
28 #else
29 class Tests
30 #endif
33 #if !__MOBILE__
34 public static int Main (string[] args) {
35 return TestDriver.RunTests (typeof (Tests), args);
37 #endif
39 public static int test_0_sin_precision () {
40 double d1 = Math.Sin (1);
41 double d2 = Math.Sin (1) - d1;
42 return (d2 == 0) ? 0 : 1;
45 public static int test_0_cos_precision () {
46 double d1 = Math.Cos (1);
47 double d2 = Math.Cos (1) - d1;
48 return (d2 == 0) ? 0 : 1;
51 public static int test_0_tan_precision () {
52 double d1 = Math.Tan (1);
53 double d2 = Math.Tan (1) - d1;
54 return (d2 == 0) ? 0 : 1;
57 public static int test_0_atan_precision () {
58 double d1 = Math.Atan (double.NegativeInfinity);
59 double d2 = Math.Atan (double.NegativeInfinity) - d1;
60 return (d2 == 0) ? 0 : 1;
63 public static int test_0_sqrt_precision () {
64 double d1 = Math.Sqrt (2);
65 double d2 = Math.Sqrt (2) - d1;
66 return (d2 == 0) ? 0 : 1;
69 public static int test_2_sqrt () {
70 return (int) Math.Sqrt (4);
72 public static int test_0_sqrt_precision_and_not_spill () {
73 double expected = 0;
74 double[] operands = new double[3];
75 double[] temporaries = new double[3];
76 for (int i = 0; i < 3; i++) {
77 operands [i] = (i+1) * (i+1) * (i+1);
78 if (i == 0) {
79 expected = operands [0];
80 } else {
81 temporaries [i] = operands [i] / expected;
82 temporaries [i] = Math.Sqrt (temporaries [i]);
83 expected = temporaries [i];
86 //Console.Write( "{0}: {1}\n", i, temporaries [i] );
88 expected = temporaries [2];
90 double result = Math.Sqrt (operands [2] / Math.Sqrt (operands [1] / operands [0]));
92 //Console.Write( "result: {0,20:G}\n", result );
94 return (result == expected) ? 0 : 1;
97 public static int test_0_sqrt_precision_and_spill () {
98 double expected = 0;
99 double[] operands = new double[9];
100 double[] temporaries = new double[9];
101 for (int i = 0; i < 9; i++) {
102 operands [i] = (i+1) * (i+1) * (i+1);
103 if (i == 0) {
104 expected = operands [0];
105 } else {
106 temporaries [i] = operands [i] / expected;
107 temporaries [i] = Math.Sqrt (temporaries [i]);
108 expected = temporaries [i];
111 //Console.Write( "{0}: {1}\n", i, temporaries [i] );
113 expected = temporaries [8];
115 double result = Math.Sqrt (operands [8] / Math.Sqrt (operands [7] / Math.Sqrt (operands [6] / Math.Sqrt (operands [5] / Math.Sqrt (operands [4] / Math.Sqrt (operands [3] / Math.Sqrt (operands [2] / Math.Sqrt (operands [1] / operands [0]))))))));
117 //Console.Write( "result: {0,20:G}\n", result );
119 return (result == expected) ? 0 : 1;
122 public static int test_0_div_precision_and_spill () {
123 double expected = 0;
124 double[] operands = new double[9];
125 double[] temporaries = new double[9];
126 for (int i = 0; i < 9; i++) {
127 operands [i] = (i+1) * (i+1);
128 if (i == 0) {
129 expected = operands [0];
130 } else {
131 temporaries [i] = operands [i] / expected;
132 expected = temporaries [i];
135 //Console.Write( "{0}: {1}\n", i, temporaries [i] );
137 expected = temporaries [8];
139 double result = (operands [8] / (operands [7] / (operands [6] / (operands [5] / (operands [4] / (operands [3] / (operands [2] / (operands [1] / operands [0]))))))));
141 //Console.Write( "result: {0,20:G}\n", result );
143 return (result == expected) ? 0 : 1;
146 public static int test_0_sqrt_nan () {
147 return Double.IsNaN (Math.Sqrt (Double.NaN)) ? 0 : 1;
150 public static int test_0_sin_nan () {
151 return Double.IsNaN (Math.Sin (Double.NaN)) ? 0 : 1;
154 public static int test_0_cos_nan () {
155 return Double.IsNaN (Math.Cos (Double.NaN)) ? 0 : 1;
158 public static int test_0_tan_nan () {
159 return Double.IsNaN (Math.Tan (Double.NaN)) ? 0 : 1;
162 public static int test_0_atan_nan () {
163 return Double.IsNaN (Math.Atan (Double.NaN)) ? 0 : 1;
166 public static int test_0_min () {
167 if (Math.Min (5, 6) != 5)
168 return 1;
169 if (Math.Min (6, 5) != 5)
170 return 2;
171 if (Math.Min (-100, -101) != -101)
172 return 3;
173 if (Math.Min ((long)5, (long)6) != 5)
174 return 4;
175 if (Math.Min ((long)6, (long)5) != 5)
176 return 5;
177 if (Math.Min ((long)-100, (long)-101) != -101)
178 return 6;
179 // this will trip if Min is accidentally using unsigned/logical comparison
180 if (Math.Min((long)-100000000000L, (long)0L) != (long)-100000000000L)
181 return 7;
182 return 0;
185 public static int test_0_max () {
186 if (Math.Max (5, 6) != 6)
187 return 1;
188 if (Math.Max (6, 5) != 6)
189 return 2;
190 if (Math.Max (-100, -101) != -100)
191 return 3;
192 if (Math.Max ((long)5, (long)6) != 6)
193 return 4;
194 if (Math.Max ((long)6, (long)5) != 6)
195 return 5;
196 if (Math.Max ((long)-100, (long)-101) != -100)
197 return 6;
198 // this will trip if Max is accidentally using unsigned/logical comparison
199 if (Math.Max((long)-100000000000L, (long)0L) != (long)0L)
200 return 7;
201 return 0;
204 public static int test_0_min_un () {
205 uint a = (uint)int.MaxValue + 10;
207 for (uint b = 7; b <= 10; ++b) {
208 if (Math.Min (a, b) != b)
209 return (int)b;
210 if (Math.Min (b, a) != b)
211 return (int)b;
214 if (Math.Min ((ulong)5, (ulong)6) != 5)
215 return 4;
216 if (Math.Min ((ulong)6, (ulong)5) != 5)
217 return 5;
219 ulong la = (ulong)long.MaxValue + 10;
221 for (ulong b = 7; b <= 10; ++b) {
222 if (Math.Min (la, b) != b)
223 return (int)b;
224 if (Math.Min (b, la) != b)
225 return (int)b;
228 return 0;
231 public static int test_0_max_un () {
232 uint a = (uint)int.MaxValue + 10;
234 for (uint b = 7; b <= 10; ++b) {
235 if (Math.Max (a, b) != a)
236 return (int)b;
237 if (Math.Max (b, a) != a)
238 return (int)b;
241 if (Math.Max ((ulong)5, (ulong)6) != 6)
242 return 4;
243 if (Math.Max ((ulong)6, (ulong)5) != 6)
244 return 5;
246 ulong la = (ulong)long.MaxValue + 10;
248 for (ulong b = 7; b <= 10; ++b) {
249 if (Math.Max (la, b) != la)
250 return (int)b;
251 if (Math.Max (b, la) != la)
252 return (int)b;
255 return 0;
258 public static int test_0_abs () {
259 double d = -5.0;
261 if (Math.Abs (d) != 5.0)
262 return 1;
263 return 0;
266 public static int test_0_float_abs () {
267 float f = -1.0f;
269 if (Math.Abs (f) != 1.0f)
270 return 1;
271 return 0;
274 public static int test_0_round () {
275 if (Math.Round (5.0) != 5.0)
276 return 1;
278 if (Math.Round (5.000000000000001) != 5.0)
279 return 2;
281 if (Math.Round (5.499999999999999) != 5.0)
282 return 3;
284 if (Math.Round (5.5) != 6.0)
285 return 4;
287 if (Math.Round (5.999999999999999) != 6.0)
288 return 5;
290 if (Math.Round (Double.Epsilon) != 0)
291 return 6;
293 if (!Double.IsNaN (Math.Round (Double.NaN)))
294 return 7;
296 if (!Double.IsPositiveInfinity (Math.Round (Double.PositiveInfinity)))
297 return 8;
299 if (!Double.IsNegativeInfinity (Math.Round (Double.NegativeInfinity)))
300 return 9;
302 if (Math.Round (Double.MinValue) != Double.MinValue)
303 return 10;
305 if (Math.Round (Double.MaxValue) != Double.MaxValue)
306 return 11;
308 return 0;
311 public static int test_0_mathf_sin () {
312 float f = MathF.Sin (3.14159f);
313 return f < 0.01f ? 0 : 1;
316 public static int test_0_mathf_cos () {
317 float f = MathF.Cos (3.14159f);
318 return f - -1f < 0.01f ? 0 : 1;
321 public static int test_0_mathf_abs () {
322 float f;
324 f = MathF.Abs (2.25f) - 2.25f;
325 if (f > 0.01f || f < -0.01f)
326 return 1;
327 f = MathF.Abs (-2.25f) - 2.25f;
328 if (f > 0.01f || f < -0.01f)
329 return 2;
330 return 0;
333 public static int test_0_mathf_sqrt () {
334 float f;
336 f = MathF.Sqrt (16.0f) - 4.0f;
337 if (f > 0.01f || f < -0.01f)
338 return 1;
339 return 0;
342 public static int test_0_mathf_max () {
343 float f;
345 f = MathF.Max (1.0f, 2.0f) - 2.0f;
346 if (f > 0.01f || f < -0.01f)
347 return 1;
348 f = MathF.Max (2.0f, 1.0f) - 2.0f;
349 if (f > 0.01f || f < -0.01f)
350 return 2;
351 return 0;
354 public static int test_0_mathf_pow () {
355 float f;
357 f = MathF.Pow (2.0f, 4.0f) - 16.0f;
358 if (f > 0.01f || f < -0.01f)
359 return 1;
360 return 0;