[amd64] Fix r8->int conversions. Fixes #26219.
[mono.git] / mono / mini / basic-float.cs
1 using System;
2 using System.Reflection;
3
4 /*
5  * Regression tests for the mono JIT.
6  *
7  * Each test needs to be of the form:
8  *
9  * public static int test_<result>_<name> ();
10  *
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.
14  *
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)
20  *
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.
24  */
25
26 /* A comparison made to same variable. */
27 #pragma warning disable 1718
28
29 #if MOBILE
30 class FloatTests
31 #else
32 class Tests
33 #endif
34 {
35
36 #if !MOBILE
37         public static int Main (string[] args) {
38                 return TestDriver.RunTests (typeof (Tests), args);
39         }
40 #endif
41         
42         public static int test_0_beq () {
43                 double a = 2.0;
44                 if (a != 2.0)
45                         return 1;
46                 return 0;
47         }
48
49         public static int test_0_bne_un () {
50                 double a = 2.0;
51                 if (a == 1.0)
52                         return 1;
53                 return 0;
54         }
55
56         public static int test_0_conv_r8 () {
57                 double a = 2;
58                 if (a != 2.0)
59                         return 1;
60                 return 0;
61         }
62
63         public static int test_0_conv_i () {
64                 double a = 2.0;
65                 int i = (int)a;
66                 if (i != 2)
67                         return 1;
68                 uint ui = (uint)a;
69                 if (ui != 2)
70                         return 2;
71                 short s = (short)a;
72                 if (s != 2)
73                         return 3;
74                 ushort us = (ushort)a;
75                 if (us != 2)
76                         return 4;
77                 byte b = (byte)a;
78                 if (b != 2)
79                         return 5;
80                 sbyte sb = (sbyte)a;
81                 if (sb != 2)
82                         return 6;
83                 /* MS.NET special cases these */
84                 double d = Double.NaN;
85                 ui = (uint)d;
86                 if (ui != 0)
87                         return 7;
88                 d = Double.PositiveInfinity;
89                 ui = (uint)d;
90                 if (ui != 0)
91                         return 8;
92                 d = Double.NegativeInfinity;
93                 ui = (uint)d;
94                 if (ui != 0)
95                         return 9;
96                 d = Double.MaxValue;
97                 i = (int)d;
98                 if (i != -2147483648)
99                         return 10;
100
101                 return 0;
102         }
103
104         public static int test_5_conv_r4 () {
105                 int i = 5;
106                 float f = (float)i;
107                 return (int)f;
108         }
109
110         public static int test_0_conv_r4_m1 () {
111                 int i = -1;
112                 float f = (float)i;
113                 return (int)f + 1;
114         }
115
116         public static int test_5_double_conv_r4 () {
117                 double d = 5.0;
118                 float f = (float)d;
119                 return (int)f;
120         }
121
122         public static int test_5_float_conv_r8 () {
123                 float f = 5.0F;
124                 double d = (double)f;
125                 return (int)d;
126         }
127
128         public static int test_5_conv_r8 () {
129                 int i = 5;
130                 double f = (double)i;
131                 return (int)f;
132         }
133
134         public static int test_5_add () {
135                 double a = 2.0;
136                 double b = 3.0;         
137                 return (int)(a + b);
138         }
139
140         public static int test_5_sub () {
141                 double a = 8.0;
142                 double b = 3.0;         
143                 return (int)(a - b);
144         }       
145
146         public static int test_24_mul () {
147                 double a = 8.0;
148                 double b = 3.0;         
149                 return (int)(a * b);
150         }       
151
152         public static int test_4_div () {
153                 double a = 8.0;
154                 double b = 2.0;         
155                 return (int)(a / b);
156         }       
157
158         public static int test_2_rem () {
159                 double a = 8.0;
160                 double b = 3.0;         
161                 return (int)(a % b);
162         }       
163
164         public static int test_2_neg () {
165                 double a = -2.0;                
166                 return (int)(-a);
167         }
168         
169         public static int test_46_float_add_spill () {
170                 // we overflow the FP stack
171                 double a = 1;
172                 double b = 2;
173                 double c = 3;
174                 double d = 4;
175                 double e = 5;
176                 double f = 6;
177                 double g = 7;
178                 double h = 8;
179                 double i = 9;
180
181                 return (int)(1.0 + (a + (b + (c + (d + (e + (f + (g + (h + i)))))))));
182         }
183
184         public static int test_4_float_sub_spill () {
185                 // we overflow the FP stack
186                 double a = 1;
187                 double b = 2;
188                 double c = 3;
189                 double d = 4;
190                 double e = 5;
191                 double f = 6;
192                 double g = 7;
193                 double h = 8;
194                 double i = 9;
195
196                 return -(int)(1.0 - (a - (b - (c - (d - (e - (f - (g - (h - i)))))))));
197                 ////// -(int)(1.0 - (1 - (2 - (3 - (4 - (5 - (6 - (7 - (8 - 9)))))))));
198         }
199
200         public static int test_362880_float_mul_spill () {
201                 // we overflow the FP stack
202                 double a = 1;
203                 double b = 2;
204                 double c = 3;
205                 double d = 4;
206                 double e = 5;
207                 double f = 6;
208                 double g = 7;
209                 double h = 8;
210                 double i = 9;
211
212                 return (int)(1.0 * (a * (b * (c * (d * (e * (f * (g * (h * i)))))))));
213         }
214
215         public static int test_4_long_cast () {
216                 long a = 1000;
217                 double d = (double)a;
218                 long b = (long)d;
219                 if (b != 1000)
220                         return 0;
221                 a = -1;
222                 d = (double)a;
223                 b = (long)d;
224                 if (b != -1)
225                         return 1;
226                 return 4;
227         }
228
229         public static int test_4_ulong_cast () {
230                 ulong a = 1000;
231                 double d = (double)a;
232                 ulong b = (ulong)d;
233                 if (b != 1000)
234                         return 0;
235                 a = 0xffffffffffffffff;
236                 float f = (float)a;
237                 if (!(f > 0f))
238                         return 1;
239                 return 4;
240         }
241
242         public static int test_4_single_long_cast () {
243                 long a = 1000;
244                 float d = (float)a;
245                 long b = (long)d;
246                 if (b != 1000)
247                         return 0;
248                 a = -1;
249                 d = (float)a;
250                 b = (long)d;
251                 if (b != -1)
252                         return 1;
253                 return 4;
254         }
255
256         public static int test_0_lconv_to_r8 () {
257                 long a = 150;
258                 double b = (double) a;
259
260                 if (b != 150.0)
261                         return 1;
262                 return 0;
263         }
264
265         public static int test_0_lconv_to_r4 () {
266                 long a = 3000;
267                 float b = (float) a;
268
269                 if (b != 3000.0F)
270                         return 1;
271                 return 0;
272         }
273
274         static void doit (double value, out long m) {
275                 m = (long) value;
276         }
277
278         public static int test_0_ftol_clobber () {
279                 long m;
280                 doit (1.3, out m);
281                 if (m != 1)
282                         return 2;
283                 return 0;
284         }
285
286         public static int test_0_rounding () {
287                 long ticks = 631502475130080000L;
288                 long ticksperday = 864000000000L;
289
290                 double days = (double) ticks / ticksperday;
291
292                 if ((int)days != 730905)
293                         return 1;
294
295                 return 0;
296         }
297
298         /* FIXME: This only works on little-endian machines */
299         /*
300         static unsafe int test_2_negative_zero () {
301                 int result = 0;
302                 double d = -0.0;
303                 float f = -0.0f;
304
305                 byte *ptr = (byte*)&d;
306                 if (ptr [7] == 0)
307                         return result;
308                 result ++;
309
310                 ptr = (byte*)&f;
311                 if (ptr [3] == 0)
312                         return result;
313                 result ++;
314
315                 return result;
316         }
317         */
318
319         public static int test_16_float_cmp () {
320                 double a = 2.0;
321                 double b = 1.0;
322                 int result = 0;
323                 bool val;
324                 
325                 val = a == a;
326                 if (!val)
327                         return result;
328                 result++;
329
330                 val = (a != a);
331                 if (val)
332                         return result;
333                 result++;
334
335                 val = a < a;
336                 if (val)
337                         return result;
338                 result++;
339
340                 val = a > a;
341                 if (val)
342                         return result;
343                 result++;
344
345                 val = a <= a;
346                 if (!val)
347                         return result;
348                 result++;
349
350                 val = a >= a;
351                 if (!val)
352                         return result;
353                 result++;
354
355                 val = b == a;
356                 if (val)
357                         return result;
358                 result++;
359
360                 val = b < a;
361                 if (!val)
362                         return result;
363                 result++;
364
365                 val = b > a;
366                 if (val)
367                         return result;
368                 result++;
369
370                 val = b <= a;
371                 if (!val)
372                         return result;
373                 result++;
374
375                 val = b >= a;
376                 if (val)
377                         return result;
378                 result++;
379
380                 val = a == b;
381                 if (val)
382                         return result;
383                 result++;
384
385                 val = a < b;
386                 if (val)
387                         return result;
388                 result++;
389
390                 val = a > b;
391                 if (!val)
392                         return result;
393                 result++;
394
395                 val = a <= b;
396                 if (val)
397                         return result;
398                 result++;
399
400                 val = a >= b;
401                 if (!val)
402                         return result;
403                 result++;
404
405                 return result;
406         }
407
408         public static int test_15_float_cmp_un () {
409                 double a = Double.NaN;
410                 double b = 1.0;
411                 int result = 0;
412                 bool val;
413                 
414                 val = a == a;
415                 if (val)
416                         return result;
417                 result++;
418
419                 val = a < a;
420                 if (val)
421                         return result;
422                 result++;
423
424                 val = a > a;
425                 if (val)
426                         return result;
427                 result++;
428
429                 val = a <= a;
430                 if (val)
431                         return result;
432                 result++;
433
434                 val = a >= a;
435                 if (val)
436                         return result;
437                 result++;
438
439                 val = b == a;
440                 if (val)
441                         return result;
442                 result++;
443
444                 val = b < a;
445                 if (val)
446                         return result;
447                 result++;
448
449                 val = b > a;
450                 if (val)
451                         return result;
452                 result++;
453
454                 val = b <= a;
455                 if (val)
456                         return result;
457                 result++;
458
459                 val = b >= a;
460                 if (val)
461                         return result;
462                 result++;
463
464                 val = a == b;
465                 if (val)
466                         return result;
467                 result++;
468
469                 val = a < b;
470                 if (val)
471                         return result;
472                 result++;
473
474                 val = a > b;
475                 if (val)
476                         return result;
477                 result++;
478
479                 val = a <= b;
480                 if (val)
481                         return result;
482                 result++;
483
484                 val = a >= b;
485                 if (val)
486                         return result;
487                 result++;
488
489                 return result;
490         }
491
492         public static int test_15_float_branch () {
493                 double a = 2.0;
494                 double b = 1.0;
495                 int result = 0;
496                 
497                 if (!(a == a))
498                         return result;
499                 result++;
500
501                 if (a < a)
502                         return result;
503                 result++;
504
505                 if (a > a)
506                         return result;
507                 result++;
508
509                 if (!(a <= a))
510                         return result;
511                 result++;
512
513                 if (!(a >= a))
514                         return result;
515                 result++;
516
517                 if (b == a)
518                         return result;
519                 result++;
520
521                 if (!(b < a))
522                         return result;
523                 result++;
524
525                 if (b > a)
526                         return result;
527                 result++;
528
529                 if (!(b <= a))
530                         return result;
531                 result++;
532
533                 if (b >= a)
534                         return result;
535                 result++;
536
537                 if (a == b)
538                         return result;
539                 result++;
540
541                 if (a < b)
542                         return result;
543                 result++;
544
545                 if (!(a > b))
546                         return result;
547                 result++;
548
549                 if (a <= b)
550                         return result;
551                 result++;
552
553                 if (!(a >= b))
554                         return result;
555                 result++;
556
557                 return result;
558         }
559
560         public static int test_15_float_branch_un () {
561                 double a = Double.NaN;
562                 double b = 1.0;
563                 int result = 0;
564                 
565                 if (a == a)
566                         return result;
567                 result++;
568
569                 if (a < a)
570                         return result;
571                 result++;
572
573                 if (a > a)
574                         return result;
575                 result++;
576
577                 if (a <= a)
578                         return result;
579                 result++;
580
581                 if (a >= a)
582                         return result;
583                 result++;
584
585                 if (b == a)
586                         return result;
587                 result++;
588
589                 if (b < a)
590                         return result;
591                 result++;
592
593                 if (b > a)
594                         return result;
595                 result++;
596
597                 if (b <= a)
598                         return result;
599                 result++;
600
601                 if (b >= a)
602                         return result;
603                 result++;
604
605                 if (a == b)
606                         return result;
607                 result++;
608
609                 if (a < b)
610                         return result;
611                 result++;
612
613                 if (a > b)
614                         return result;
615                 result++;
616
617                 if (a <= b)
618                         return result;
619                 result++;
620
621                 if (a >= b)
622                         return result;
623                 result++;
624
625                 return result;
626         }
627
628         public static int test_0_float_precision () {
629                 float f1 = 3.40282346638528859E+38f;
630                 float f2 = 3.40282346638528859E+38f;            
631                 float PositiveInfinity =  1.0f / 0.0f;
632                 float f = f1 + f2;
633
634                 return f == PositiveInfinity ? 0 : 1;
635         }
636
637         static double VALUE = 0.19975845134874831D;
638
639         public static int test_0_float_conversion_reduces_double_precision () {
640                 double d = (float)VALUE;
641                 if (d != 0.19975845515727997d)
642                         return 1;
643
644                 return 0;
645         }
646
647         /* This doesn't work with llvm */
648         /*
649     public static int test_0_long_to_double_conversion ()
650     {
651                 long l = 9223372036854775807L;
652                 long conv = (long)((double)l);
653                 if (conv != -9223372036854775808L)
654                         return 1;
655
656                 return 0;
657     }
658         */
659
660         public static int INT_VAL = 0x13456799;
661
662         public static int test_0_int4_to_float_convertion ()
663     {
664                 double d = (double)(float)INT_VAL;
665
666                 if (d != 323315616)
667                         return 1;
668                 return 0;
669         }
670
671         public static int test_0_int8_to_float_convertion ()
672     {
673                 double d = (double)(float)(long)INT_VAL;
674
675                 if (d != 323315616)
676                         return 1;
677                 return 0;
678         }
679 }
680