Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / objects.cs
1 using System;
2 using System.Text;
3 using System.Reflection;
4 using System.Runtime.InteropServices;
5 using System.Runtime.CompilerServices;
6
7 /*
8  * Regression tests for the mono JIT.
9  *
10  * Each test needs to be of the form:
11  *
12  * static int test_<result>_<name> ();
13  *
14  * where <result> is an integer (the value that needs to be returned by
15  * the method to make it pass.
16  * <name> is a user-displayed name used to identify the test.
17  *
18  * The tests can be driven in two ways:
19  * *) running the program directly: Main() uses reflection to find and invoke
20  *      the test methods (this is useful mostly to check that the tests are correct)
21  * *) with the --regression switch of the jit (this is the preferred way since
22  *      all the tests will be run with optimizations on and off)
23  *
24  * The reflection logic could be moved to a .dll since we need at least another
25  * regression test file written in IL code to have better control on how
26  * the IL code looks.
27  */
28
29 #if __MOBILE__
30 namespace ObjectTests
31 {
32 #endif
33
34 struct Simple {
35         public int a;
36         public byte b;
37         public short c;
38         public long d;
39 }
40
41 struct Small {
42         public byte b1;
43         public byte b2;
44 }
45
46 // Size=2, Align=1
47 struct Foo {
48         bool b1;
49         bool b2;
50 }
51
52 struct Large {
53         int one;
54         int two;
55         long three;
56         long four;
57         int five;
58         long six;
59         int seven;
60         long eight;
61         long nine;
62         long ten;
63
64         public void populate ()
65         {
66                 one = 1; two = 2;
67                 three = 3; four = 4;
68                 five = 5; six = 6;
69                 seven = 7; eight = 8;
70                 nine = 9; ten = 10;
71         }
72         public bool check ()
73         {
74                 return one == 1  && two == 2  &&
75                         three == 3  && four == 4  &&
76                         five == 5  && six == 6  &&
77                         seven == 7  && eight == 8  &&
78                         nine == 9  && ten == 10;
79         }
80 }
81
82 class Sample {
83         public int a;
84         public Sample (int v) {
85                 a = v;
86         }
87 }
88
89 [StructLayout ( LayoutKind.Explicit )]
90 struct StructWithBigOffsets {
91                 [ FieldOffset(10000) ] public byte b;
92                 [ FieldOffset(10001) ] public sbyte sb;
93                 [ FieldOffset(11000) ] public short s;
94                 [ FieldOffset(11002) ] public ushort us;
95                 [ FieldOffset(12000) ] public uint i;
96                 [ FieldOffset(12004) ] public int si;
97                 [ FieldOffset(13000) ] public long l;
98                 [ FieldOffset(14000) ] public float f;
99                 [ FieldOffset(15000) ] public double d;
100 }
101
102 enum SampleEnum {
103         A,
104         B,
105         C
106 }
107
108 struct Alpha {
109         public long a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;
110 }
111
112 struct Beta {
113         public Alpha a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;
114 }
115
116 struct Gamma {
117         public Beta a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;
118 }
119
120 class Tests {
121
122 #if !__MOBILE__
123         public static int Main (string[] args) {
124                 return TestDriver.RunTests (typeof (Tests), args);
125         }
126 #endif
127         
128         public static int test_0_return () {
129                 Simple s;
130                 s.a = 1;
131                 s.b = 2;
132                 s.c = (short)(s.a + s.b);
133                 s.d = 4;
134                 return s.a - 1;
135         }
136
137         public static int test_0_string_access () {
138                 string s = "Hello";
139                 if (s [1] != 'e')
140                         return 1;
141                 return 0;
142         }
143
144         public static int test_0_string_virtual_call () {
145                 string s = "Hello";
146                 string s2 = s.ToString ();
147                 if (s2 [1] != 'e')
148                         return 1;
149                 return 0;
150         }
151
152         public static int test_0_iface_call () {
153                 string s = "Hello";
154                 object o = ((ICloneable)s).Clone ();
155                 return 0;
156         }
157
158         public static int test_5_newobj () {
159                 Sample s = new Sample (5);
160                 return s.a;
161         }
162
163         public static int test_4_box () {
164                 object obj = 4;
165                 return (int)obj;
166         }
167
168         public static int test_0_enum_unbox () {
169                 SampleEnum x = SampleEnum.A;
170                 object o = x;
171                 
172                 int res = 1;
173
174                 res = (int)o;
175                 
176                 return res;
177         }
178         
179         static Simple get_simple (int v) {
180                 Simple r = new Simple ();
181                 r.a = v;
182                 r.b = (byte)(v + 1);
183                 r.c = (short)(v + 2);
184                 r.d = v + 3;
185
186                 return r;
187         }
188
189         public static int test_3_return_struct () {
190                 Simple v = get_simple (1);
191
192                 if (v.a != 1)
193                         return 0;
194                 if (v.b != 2)
195                         return 0;
196                 if (v.c != 3)
197                         return 0;
198                 if (v.d != 4)
199                         return 0;
200                 return 3;
201         }
202
203         public virtual Simple v_get_simple (int v)
204         {
205                 return get_simple (v);
206         }
207         
208         public static int test_2_return_struct_virtual () {
209                 Tests t = new Tests ();
210                 Simple v = t.v_get_simple (2);
211
212                 if (v.a != 2)
213                         return 0;
214                 if (v.b != 3)
215                         return 0;
216                 if (v.c != 4)
217                         return 0;
218                 if (v.d != 5)
219                         return 0;
220                 return 2;
221         }
222
223         static int receive_simple (int a, Simple v, int b) {
224                 if (v.a != 1)
225                         return 1;
226                 if (v.b != 2)
227                         return 2;
228                 if (v.c != 3)
229                         return 3;
230                 if (v.d != 4)
231                         return 4;
232                 if (a != 7)
233                         return 5;
234                 if (b != 9)
235                         return 6;
236                 return 0;
237         }
238         
239         public static int test_5_pass_struct () {
240                 Simple v = get_simple (1);
241                 if (receive_simple (7, v, 9) != 0)
242                         return 0;
243                 if (receive_simple (7, get_simple (1), 9) != 0)
244                         return 1;
245                 return 5;
246         }
247
248         static Simple s_v;
249         public static int test_5_pass_static_struct () {
250                 s_v = get_simple (1);
251                 if (receive_simple (7, s_v, 9) != 0)
252                         return 0;
253                 return 5;
254         }
255
256         // Test alignment of small structs
257
258         static Small get_small (byte v) {
259                 Small r = new Small ();
260         
261                 r.b1 = v;
262                 r.b2 = (byte)(v + 1);
263
264                 return r;
265         }
266
267         static Small return_small (Small s) {
268                 return s;
269         }
270
271         static int receive_small (int a, Small v, int b) {
272                 if (v.b1 != 1)
273                         return 1;
274                 if (v.b2 != 2)
275                         return 2;
276                 return 0;
277         }
278
279         static int receive_small_sparc_many_args (int a, int a2, int a3, int a4, int a5, int a6, Small v, int b) {
280                 if (v.b1 != 1)
281                         return 1;
282                 if (v.b2 != 2)
283                         return 2;
284                 return 0;
285         }
286
287         public static int test_5_pass_small_struct () {
288                 Small v = get_small (1);
289                 if (receive_small (7, v, 9) != 0)
290                         return 0;
291                 if (receive_small (7, get_small (1), 9) != 0)
292                         return 1;
293                 if (receive_small_sparc_many_args (1, 2, 3, 4, 5, 6, v, 9) != 0)
294                         return 2;
295                 v = return_small (v);
296                 if (v.b1 != 1)
297                         return 3;
298                 if (v.b2 != 2)
299                         return 4;
300                 return 5;
301         }
302
303         // 64-bits, 32-bit aligned
304         struct struct1 {
305                 public int      a;
306                 public int      b;
307         };
308
309         static int check_struct1(struct1 x) {
310                 if (x.a != 1)
311                         return 1;
312                 if (x.b != 2)
313                         return 2;
314                 return 0;
315         }
316
317         static int pass_struct1(int a, int b, struct1 x) {
318                 if (a != 3)
319                         return 3;
320                 if (b != 4)
321                         return 4;
322                 return check_struct1(x);
323         }
324
325         static int pass_struct1(int a, struct1 x) {
326                 if (a != 3)
327                         return 3;
328                 return check_struct1(x);
329         }
330
331         static int pass_struct1(struct1 x) {
332                 return check_struct1(x);
333         }
334
335         public static int test_0_struct1_args () {
336                 int r;
337                 struct1 x;
338
339                 x.a = 1;
340                 x.b = 2;
341                 if ((r = check_struct1(x)) != 0)
342                         return r;
343                 if ((r = pass_struct1(x)) != 0)
344                         return r + 10;
345                 if ((r = pass_struct1(3, x)) != 0)
346                         return r + 20;
347                 if ((r = pass_struct1(3, 4, x)) != 0)
348                         return r + 30;
349                 return 0;
350         }
351
352         // 64-bits, 64-bit aligned
353         struct struct2 {
354                 public long     a;
355         };
356
357         static int check_struct2(struct2 x) {
358                 if (x.a != 1)
359                         return 1;
360                 return 0;
361         }
362
363         static int pass_struct2(int a, int b, int c, struct2 x) {
364                 if (a != 3)
365                         return 3;
366                 if (b != 4)
367                         return 4;
368                 if (c != 5)
369                         return 5;
370                 return check_struct2(x);
371         }
372
373         static int pass_struct2(int a, int b, struct2 x) {
374                 if (a != 3)
375                         return 3;
376                 if (b != 4)
377                         return 4;
378                 return check_struct2(x);
379         }
380
381         static int pass_struct2(int a, struct2 x) {
382                 if (a != 3)
383                         return 3;
384                 return check_struct2(x);
385         }
386
387         static int pass_struct2(struct2 x) {
388                 return check_struct2(x);
389         }
390
391         public static int test_0_struct2_args () {
392                 int r;
393                 struct2 x;
394
395                 x.a = 1;
396                 if ((r = check_struct2(x)) != 0)
397                         return r;
398                 if ((r = pass_struct2(x)) != 0)
399                         return r + 10;
400                 if ((r = pass_struct2(3, x)) != 0)
401                         return r + 20;
402                 if ((r = pass_struct2(3, 4, x)) != 0)
403                         return r + 30;
404                 if ((r = pass_struct2(3, 4, 5, x)) != 0)
405                         return r + 40;
406                 return 0;
407         }
408
409         // 128 bits
410         struct Struct3 {
411                 public long i, j, k, l;
412         }
413
414         static int pass_struct3 (int i, int j, int k, int l, int m, int n, int o, int p, Struct3 s, int q) {
415                 if (s.i + s.j + s.k + s.l != 10)
416                         return 1;
417                 else
418                         return 0;
419         }
420
421         public static int test_0_struct3_args () {
422                 Struct3 s = new Struct3 ();
423                 s.i = 1;
424                 s.j = 2;
425                 s.k = 3;
426                 s.l = 4;
427
428                 return pass_struct3 (1, 2, 3, 4, 5, 6, 7, 8, s, 9);
429         }
430
431         // Struct with unaligned size on 64 bit machines
432         struct Struct4 {
433         public int i, j, k, l, m;
434                 public int i1, i2, i3, i4, i5, i6;
435         }
436
437         static int pass_struct4 (Struct4 s) {
438                 if (s.i + s.j + s.k + s.l + s.m != 15)
439                         return 1;
440                 else
441                         return 0;
442         }
443
444         public static int test_0_struct4_args () {
445                 Struct4 s = new Struct4 ();
446                 s.i = 1;
447                 s.j = 2;
448                 s.k = 3;
449                 s.l = 4;
450                 s.m = 5;
451
452                 return pass_struct4 (s);
453         }
454
455
456
457         struct AStruct {
458                 public int i;
459
460                 public AStruct (int i) {
461                         this.i = i;
462                 }
463
464                 public override int GetHashCode () {
465                         return i;
466                 }
467         }
468
469         // Test that vtypes are unboxed during a virtual call
470         public static int test_44_unbox_trampoline () {
471                 AStruct s = new AStruct (44);
472                 object o = s;
473                 return o.GetHashCode ();
474         }
475
476         public static int test_0_unbox_trampoline2 () {
477                 int i = 12;
478                 object o = i;
479                         
480                 if (i.ToString () != "12")
481                         return 1;
482                 if (((Int32)o).ToString () != "12")
483                         return 2;
484                 if (o.ToString () != "12")
485                         return 3;
486                 return 0;
487         }
488
489         // Test fields with big offsets
490         public static int test_0_fields_with_big_offsets () {
491                 StructWithBigOffsets s = new StructWithBigOffsets ();
492                 StructWithBigOffsets s2 = new StructWithBigOffsets ();
493
494                 s.b = 0xde;
495                 s.sb = 0xe;
496                 s.s = 0x12de;
497                 s.us = 0x12da;
498                 s.i = 0xdeadbeef;
499                 s.si = 0xcafe;
500                 s.l = 0xcafebabe;
501                 s.f = 3.14F;
502                 s.d = 3.14;
503
504                 s2.b = s.b;
505                 s2.sb = s.sb;
506                 s2.s = s.s;
507                 s2.us = s.us;
508                 s2.i = s.i;
509                 s2.si = s.si;
510                 s2.l = s.l;
511                 s2.f = s.f;
512                 s2.d = s.d;
513
514                 if (s2.b != 0xde)
515                         return 1;
516                 if (s2.s != 0x12de)
517                         return 2;
518                 if (s2.i != 0xdeadbeef)
519                         return 3;
520                 if (s2.l != 0xcafebabe)
521                         return 4;
522                 if (s2.f != 3.14F)
523                         return 5;
524                 if (s2.d != 3.14)
525                         return 6;
526                 if (s2.sb != 0xe)
527                         return 7;
528                 if (s2.us != 0x12da)
529                         return 9;
530                 if (s2.si != 0xcafe)
531                         return 10;
532
533                 return 0;
534         }
535
536         class TestRegA {
537
538                 long buf_start;
539                 int buf_length, buf_offset;
540
541                 public TestRegA () {
542                         buf_start = 0;
543                         buf_length = 0;
544                         buf_offset = 0;
545                 }
546         
547                 public long Seek (long position) {
548                         long pos = position;
549                         /* interaction between the register allocator and
550                          * allocating arguments to registers */
551                         if (pos >= buf_start && pos <= buf_start + buf_length) {
552                                 buf_offset = (int) (pos - buf_start);
553                                 return pos;
554                         }
555                         return buf_start;
556                 }
557
558         }
559
560         public static int test_0_seektest () {
561                 TestRegA t = new TestRegA ();
562                 return (int)t.Seek (0);
563         }
564
565         class Super : ICloneable {
566                 public virtual object Clone () {
567                         return null;
568                 }
569         }
570         class Duper: Super {
571         }
572
573         public static int test_0_null_cast () {
574                 object o = null;
575
576                 Super s = (Super)o;
577
578                 return 0;
579         }
580         
581         public static int test_0_super_cast () {
582                 Duper d = new Duper ();
583                 Super sup = d;
584                 Object o = d;
585
586                 if (!(o is Super))
587                         return 1;
588                 try {
589                         d = (Duper)sup;
590                 } catch {
591                         return 2;
592                 }
593                 if (!(d is Object))
594                         return 3;
595                 try {
596                         d = (Duper)(object)sup;
597                 } catch {
598                         return 4;
599                 }
600                 return 0;
601         }
602
603         public static int test_0_super_cast_array () {
604                 Duper[] d = new Duper [0];
605                 Super[] sup = d;
606                 Object[] o = d;
607
608                 if (!(o is Super[]))
609                         return 1;
610                 try {
611                         d = (Duper[])sup;
612                 } catch {
613                         return 2;
614                 }
615                 if (!(d is Object[]))
616                         return 3;
617                 try {
618                         d = (Duper[])(object[])sup;
619                 } catch {
620                         return 4;
621                 }
622                 return 0;
623         }
624
625         public static int test_0_multi_array_cast () {
626                 Duper[,] d = new Duper [1, 1];
627                 object[,] o = d;
628
629                 try {
630                         o [0, 0] = new Super ();
631                         return 1;
632                 }
633                 catch (ArrayTypeMismatchException) {
634                 }
635
636                 return 0;
637         }
638
639         public static int test_0_vector_array_cast () {
640                 Array arr1 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0});
641                 Array arr2 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {10});
642                 Array arr5 = Array.CreateInstance (typeof (string), new int[] {1}, new int[] {10});
643
644                 if (arr1.GetType () != typeof (int[]))
645                         return 1;
646
647                 if (arr2.GetType () == typeof (int[]))
648                         return 2;
649
650                 int[] b;
651
652                 b = (int[])arr1;
653
654                 try {
655                         b = (int[])arr2;
656                         return 3;
657                 }
658                 catch (InvalidCastException) {
659                 }
660
661                 if (arr2 is int[])
662                         return 4;
663                 var as_object_arr = arr5 as object [];
664                 if (as_object_arr != null)
665                         return 5;
666
667                 int [,] [] arr3 = new int [1, 1] [];
668                 object o = arr3;
669                 int [,] [] arr4 = (int [,] [])o;
670
671                 return 0;
672         }
673
674         public static int test_0_enum_array_cast () {
675                 TypeCode[] tc = new TypeCode [0];
676                 object[] oa;
677                 ValueType[] vta;
678                 int[] inta;
679                 Array a = tc;
680                 bool ok;
681
682                 if (a is object[])
683                         return 1;
684                 if (a is ValueType[])
685                         return 2;
686                 if (a is Enum[])
687                         return 3;
688                 try {
689                         ok = false;
690                         oa = (object[])a;
691                 } catch {
692                         ok = true;
693                 }
694                 if (!ok)
695                         return 4;
696                 try {
697                         ok = false;
698                         vta = (ValueType[])a;
699                 } catch {
700                         ok = true;
701                 }
702                 if (!ok)
703                         return 5;
704                 try {
705                         ok = true;
706                         inta = (int[])a;
707                 } catch {
708                         ok = false;
709                 }
710                 if (!ok)
711                         return 6;
712                 return 0;
713         }
714
715         public static int test_0_more_cast_corner_cases () {
716                 ValueType[] vta = new ValueType [0];
717                 Enum[] ea = new Enum [0];
718                 Array a = vta;
719                 object[] oa;
720                 bool ok;
721
722                 if (!(a is object[]))
723                         return 1;
724                 if (!(a is ValueType[]))
725                         return 2;
726                 if (a is Enum[])
727                         return 3;
728                 a = ea;
729                 if (!(a is object[]))
730                         return 4;
731                 if (!(a is ValueType[]))
732                         return 5;
733                 if (!(a is Enum[]))
734                         return 6;
735
736                 try {
737                         ok = true;
738                         oa = (object[])a;
739                 } catch {
740                         ok = false;
741                 }
742                 if (!ok)
743                         return 7;
744         
745                 try {
746                         ok = true;
747                         oa = (Enum[])a;
748                 } catch {
749                         ok = false;
750                 }
751                 if (!ok)
752                         return 8;
753         
754                 try {
755                         ok = true;
756                         oa = (ValueType[])a;
757                 } catch {
758                         ok = false;
759                 }
760                 if (!ok)
761                         return 9;
762
763                 a = vta;
764                 try {
765                         ok = true;
766                         oa = (object[])a;
767                 } catch {
768                         ok = false;
769                 }
770                 if (!ok)
771                         return 10;
772         
773                 try {
774                         ok = true;
775                         oa = (ValueType[])a;
776                 } catch {
777                         ok = false;
778                 }
779                 if (!ok)
780                         return 11;
781         
782                 try {
783                         ok = false;
784                         vta = (Enum[])a;
785                 } catch {
786                         ok = true;
787                 }
788                 if (!ok)
789                         return 12;
790                 return 0;
791         }
792
793         public static int test_0_cast_iface_array () {
794                 object o = new ICloneable [0];
795                 object o2 = new Duper [0];
796                 object t;
797                 bool ok;
798
799                 if (!(o is object[]))
800                         return 1;
801                 if (!(o2 is ICloneable[]))
802                         return 2;
803
804                 try {
805                         ok = true;
806                         t = (object[])o;
807                 } catch {
808                         ok = false;
809                 }
810                 if (!ok)
811                         return 3;
812         
813                 try {
814                         ok = true;
815                         t = (ICloneable[])o2;
816                 } catch {
817                         ok = false;
818                 }
819                 if (!ok)
820                         return 4;
821
822                 try {
823                         ok = true;
824                         t = (ICloneable[])o;
825                 } catch {
826                         ok = false;
827                 }
828                 if (!ok)
829                         return 5;
830
831                 if (!(o is ICloneable[]))
832                         return 6;
833
834                 /* add tests for interfaces that 'inherit' interfaces */
835                 return 0;
836         }
837
838         private static int[] daysmonthleap = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
839
840         private static int AbsoluteDays (int year, int month, int day)
841         {
842                 int temp = 0, m = 1;
843                 int[] days = daysmonthleap;
844                 while (m < month)
845                         temp += days[m++];
846                 return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400));
847         }
848
849         public static int test_719162_complex_div () {
850                 int adays = AbsoluteDays (1970, 1, 1);
851                 return adays;
852         }
853
854         delegate int GetIntDel ();
855
856         static int return4 () {
857                 return 4;
858         }
859
860         int return5 () {
861                 return 5;
862         }
863
864         public static int test_2_static_delegate () {
865                 GetIntDel del = new GetIntDel (return4);
866                 int v = del ();
867                 if (v != 4)
868                         return 0;
869                 return 2;
870         }
871
872         public static int test_2_instance_delegate () {
873                 Tests t = new Tests ();
874                 GetIntDel del = new GetIntDel (t.return5);
875                 int v = del ();
876                 if (v != 5)
877                         return 0;
878                 return 2;
879         }
880
881         class InstanceDelegateTest {
882                 public int a;
883
884                 public int return_field () {
885                         return a;
886                 }
887         }
888
889         public static int test_2_instance_delegate_with_field () {
890                 InstanceDelegateTest t = new InstanceDelegateTest () { a = 1337 };
891                 GetIntDel del = new GetIntDel (t.return_field);
892                 int v = del ();
893                 if (v != 1337)
894                         return 0;
895                 return 2;
896         }
897
898         interface IFaceVirtualDel {
899                 int return_field ();
900         }
901
902         struct VtypeVirtualDelStruct : IFaceVirtualDel {
903                 public int f;
904                 public int return_field_nonvirt () {
905                         return f;
906                 }
907                 public int return_field () {
908                         return f;
909                 }
910         }
911
912         public static int test_42_vtype_delegate () {
913                 var s = new VtypeVirtualDelStruct () { f = 42 };
914                 Func<int> f = s.return_field_nonvirt;
915                 return f ();
916         }
917
918         public static int test_42_vtype_virtual_delegate () {
919                 IFaceVirtualDel s = new VtypeVirtualDelStruct () { f = 42 };
920                 Func<int> f = s.return_field;
921                 return f ();
922         }
923
924         public static int test_1_store_decimal () {
925                 decimal[,] a = {{1}};
926
927                 if (a[0,0] != 1m)
928                         return 0;
929                 return 1;
930         }
931
932         public static int test_2_intptr_stobj () {
933                 System.IntPtr [] arr = { new System.IntPtr () };
934
935                 if (arr [0] != (System.IntPtr)0)
936                         return 1;
937                 return 2;
938         }
939
940         static int llmult (int a, int b, int c, int d) {
941                 return a + b + c + d;
942         }
943
944         /* 
945          * Test that evaluation of complex arguments does not overwrite the
946          * arguments already in outgoing registers.
947          */
948         public static int test_155_regalloc () {
949                 int a = 10;
950                 int b = 10;
951
952                 int c = 0;
953                 int d = 0;
954                 int[] arr = new int [5];
955
956                 return llmult (arr [c + d], 150, 5, 0);
957         }
958
959         static bool large_struct_test (Large a, Large b, Large c, Large d)
960         {
961                 if (!a.check ()) return false;
962                 if (!b.check ()) return false;
963                 if (!c.check ()) return false;
964                 if (!d.check ()) return false;
965                 return true;
966         }
967
968         public static int test_2_large_struct_pass ()
969         {
970                 Large a, b, c, d;
971                 a = new Large ();
972                 b = new Large ();
973                 c = new Large ();
974                 d = new Large ();
975                 a.populate ();
976                 b.populate ();
977                 c.populate ();
978                 d.populate ();
979                 if (large_struct_test (a, b, c, d))
980                         return 2;
981                 return 0;
982         }
983
984         public static unsafe int test_0_pin_string () {
985                 string x = "xxx";
986                 fixed (char *c = x) {
987                         if (*c != 'x')
988                                 return 1;
989                 }
990                 return 0;
991         }
992         
993         public static int my_flags;
994         public static int test_0_and_cmp_static ()
995         {
996                 
997                 /* various forms of test [mem], imm */
998                 
999                 my_flags = 0x01020304;
1000                 
1001                 if ((my_flags & 0x01020304) == 0)
1002                         return 1;
1003                 
1004                 if ((my_flags & 0x00000304) == 0)
1005                         return 2;
1006                 
1007                 if ((my_flags & 0x00000004) == 0)
1008                         return 3;
1009                 
1010                 if ((my_flags & 0x00000300) == 0)
1011                         return 4;
1012                 
1013                 if ((my_flags & 0x00020000) == 0)
1014                         return 5;
1015                 
1016                 if ((my_flags & 0x01000000) == 0)
1017                         return 6;
1018                 
1019                 return 0;
1020         }
1021         
1022         static byte b;
1023         public static int test_0_byte_compares ()
1024         {
1025                 b = 0xff;
1026                 if (b == -1)
1027                         return 1;
1028                 b = 0;
1029                 if (!(b < System.Byte.MaxValue))
1030                         return 2;
1031                 
1032                 if (!(b <= System.Byte.MaxValue))
1033                         return 3;
1034                 
1035                 return 0;
1036         }
1037
1038         static Nullable<bool> s_nullb;
1039         static AStruct s_struct1;
1040
1041         /* test if VES uses correct sizes for value type write to static field */
1042         public static int test_0_static_nullable_bool () {
1043                 s_struct1 = new AStruct (0x1337dead);
1044                 s_nullb = true;
1045                 /* make sure that the write to s_nullb didn't smash the value after it */
1046                 if (s_struct1.i != 0x1337dead)
1047                         return 2;
1048                 return 0;
1049         }
1050
1051         public static int test_71_long_shift_right () {
1052                 ulong value = 38654838087;
1053                 int x = 0;
1054                 byte [] buffer = new byte [1];
1055                 buffer [x] = ((byte)(value >> x));
1056                 return buffer [x];
1057         }
1058         
1059         static long x;
1060         public static int test_0_addsub_mem ()
1061         {
1062                 x = 0;
1063                 x += 5;
1064                 
1065                 if (x != 5)
1066                         return 1;
1067                 
1068                 x -= 10;
1069                 
1070                 if (x != -5)
1071                         return 2;
1072                 
1073                 return 0;
1074         }
1075         
1076         static ulong y;
1077         public static int test_0_sh32_mem ()
1078         {
1079                 y = 0x0102130405060708;
1080                 y >>= 32;
1081                 
1082                 if (y != 0x01021304)
1083                         return 1;
1084                 
1085                 y = 0x0102130405060708;
1086                 y <<= 32;
1087                 
1088                 if (y != 0x0506070800000000)
1089                         return 2;
1090                 
1091                 x = 0x0102130405060708;
1092                 x <<= 32;
1093                 
1094                 if (x != 0x0506070800000000)
1095                         return 2;
1096                 
1097                 return 0;
1098         }
1099
1100
1101         static uint dum_de_dum = 1;
1102         public static int test_0_long_arg_opt ()
1103         {
1104                 return Foo (0x1234567887654321, dum_de_dum);
1105         }
1106         
1107         static int Foo (ulong x, ulong y)
1108         {
1109                 if (x != 0x1234567887654321)
1110                         return 1;
1111                 
1112                 if (y != 1)
1113                         return 2;
1114                 
1115                 return 0;
1116         }
1117         
1118         public static int test_0_long_ret_opt ()
1119         {
1120                 ulong x = X ();
1121                 if (x != 0x1234567887654321)
1122                         return 1;
1123                 ulong y = Y ();
1124                 if (y != 1)
1125                         return 2;
1126                 
1127                 return 0;
1128         }
1129         
1130         static ulong X ()
1131         {
1132                 return 0x1234567887654321;
1133         }
1134         
1135         static ulong Y ()
1136         {
1137                 return dum_de_dum;
1138         }
1139
1140         /* from bug# 71515 */
1141         static int counter = 0;
1142         static bool WriteStuff () {
1143                 counter = 10;
1144                 return true;
1145         }
1146         public static int test_0_cond_branch_side_effects () {
1147                 counter = 5;
1148                 if (WriteStuff()) {
1149                 }
1150                 if (counter == 10)
1151                         return 0;
1152                 return 1;
1153         }
1154
1155         // bug #74992
1156         public static int arg_only_written (string file_name, int[]
1157 ncells ) {
1158                 if (file_name == null)
1159                         return 1;
1160
1161                 ncells = foo ();
1162                 bar (ncells [0]);
1163
1164                 return 0;
1165         }
1166
1167         public static int[] foo () {
1168                 return new int [3];
1169         }
1170
1171         public static void bar (int i) {
1172         }
1173         
1174
1175         public static int test_0_arg_only_written ()
1176         {
1177                 return arg_only_written ("md.in", null);
1178         }               
1179
1180         static long position = 0;
1181
1182         public static int test_4_static_inc_long () {
1183
1184                 int count = 4;
1185
1186                 position = 0;
1187
1188                 position += count;
1189
1190                 return (int)position;
1191         }
1192
1193         struct FooStruct {
1194
1195                 public FooStruct (long l) {
1196                 }
1197         }
1198
1199         public static int test_0_calls_opcode_emulation () {
1200                 // Test that emulated opcodes do not clobber arguments already in
1201                 // out registers
1202                 checked {
1203                         long val = 10000;
1204                         new FooStruct (val * 10000);
1205                 }
1206                 return 0;
1207         }
1208
1209         public static int test_0_intrins_string_length () {
1210                 string s = "ABC";
1211
1212                 return (s.Length == 3) ? 0 : 1;
1213         }
1214
1215         public static int test_0_intrins_string_chars () {
1216                 string s = "ABC";
1217
1218                 return (s [0] == 'A' && s [1] == 'B' && s [2] == 'C') ? 0 : 1;
1219         }
1220
1221         public static int test_0_intrins_object_gettype () {
1222                 object o = 1;
1223
1224                 return (o.GetType () == typeof (int)) ? 0 : 1;
1225         }
1226
1227         public static int test_0_intrins_object_gethashcode () {
1228                 object o = new Object ();
1229
1230                 return (o.GetHashCode () == o.GetHashCode ()) ? 0 : 1;
1231         }
1232
1233         class FooClass {
1234         }
1235
1236         public static int test_0_intrins_object_ctor () {
1237                 object o = new FooClass ();
1238
1239                 return (o != null) ? 0 : 1;
1240         }
1241
1242         public static int test_0_intrins_array_rank () {
1243                 int[,] a = new int [10, 10];
1244
1245                 return (a.Rank == 2) ? 0 : 1;
1246         }
1247
1248         public static int test_0_intrins_array_length () {
1249                 int[,] a = new int [10, 10];
1250                 Array a2 = a;
1251
1252                 return (a2.Length == 100) ? 0 : 1;
1253         }
1254
1255         public static int test_0_intrins_runtimehelpers_offset_to_string_data () {
1256                 int i = RuntimeHelpers.OffsetToStringData;
1257                 
1258                 return i - i;
1259         }
1260
1261         public static int test_0_intrins_string_setchar () {
1262                 StringBuilder sb = new StringBuilder ("ABC");
1263
1264                 sb [1] = 'D';
1265
1266                 return sb.ToString () == "ADC" ? 0 : 1;
1267         }
1268
1269         public class Bar {
1270                 bool allowLocation = true;
1271         Foo f = new Foo ();     
1272         }
1273
1274         public static int test_0_regress_78990_unaligned_structs () {
1275                 new Bar ();
1276
1277                 return 0;
1278         }
1279
1280         public static unsafe int test_97_negative_index () {
1281                 char[] arr = new char[] {'a', 'b'};
1282                 fixed (char *p = arr) {
1283                         char *i = p + 2;
1284                         char a = i[-2];
1285                         return a;
1286                 }
1287         }
1288
1289         /* bug #82281 */
1290         public static int test_0_unsigned_right_shift_imm0 () {
1291                 uint temp = 0;
1292                 byte[] data = new byte[256];
1293                 for (int i = 0; i < 1; i ++)
1294                         temp = (uint)(data[temp >> 24] | data[temp >> 0]);
1295                 return 0;
1296         }
1297
1298         class Foo2 {
1299                 public virtual int foo () {
1300                         return 0;
1301                 }
1302         }
1303
1304         sealed class Bar2 : Foo2 {
1305                 public override int foo () {
1306                         return 0;
1307                 }
1308         }
1309
1310         public static int test_0_abcrem_check_this_removal () {
1311                 Bar2 b = new Bar2 ();
1312
1313                 // The check_this generated here by the JIT should be removed
1314                 b.foo ();
1315
1316                 return 0;
1317         }
1318
1319         static int invoke_twice (Bar2 b) {
1320                 b.foo ();
1321                 // The check_this generated here by the JIT should be removed
1322                 b.foo ();
1323
1324                 return 0;
1325         }
1326
1327         public static int test_0_abcrem_check_this_removal2 () {
1328                 Bar2 b = new Bar2 ();
1329
1330                 invoke_twice (b);
1331
1332                 return 0;
1333         }
1334
1335         /* #346563 */
1336         public static int test_0_array_access_64_bit () {
1337                 int[] arr2 = new int [10];
1338                 for (int i = 0; i < 10; ++i)
1339                         arr2 [i] = i;
1340                 string s = "ABCDEFGH";
1341
1342                 byte[] arr = new byte [4];
1343                 arr [0] = 252;
1344                 arr [1] = 255;
1345                 arr [2] = 255;
1346                 arr [3] = 255;
1347
1348                 int len = arr [0] | (arr [1] << 8) | (arr [2] << 16) | (arr [3] << 24);
1349                 int len2 = - (len + 2);
1350
1351                 // Test array and string access with a 32 bit value whose upper 32 bits are
1352                 // undefined
1353                 // len2 = 3
1354                 if (arr2 [len2] != 2)
1355                         return 1;
1356                 if (s [len2] != 'C')
1357                         return 2;
1358                 return 0;
1359         }
1360
1361         public static float return_float () {
1362                 return 1.4e-45f;
1363         }
1364
1365         public static int test_0_float_return_spill () {
1366                 // The return value of return_float () is spilled because of the
1367                 // boxing call
1368                 object o = return_float ();
1369                 float f = return_float ();
1370                 return (float)o == f ? 0 : 1;
1371         }
1372
1373         class R4Holder {
1374                 public static float pi = 3.14f;
1375
1376                 public float float_field;
1377         }
1378
1379         public static int test_0_ldsfld_soft_float () {
1380                 if (R4Holder.pi == 3.14f)
1381                         return 0;
1382                 else
1383                         return 1;
1384         }
1385
1386         public static int test_0_ldfld_stfld_soft_float () {
1387                 R4Holder h = new R4Holder ();
1388                 h.float_field = 3.14f;
1389
1390                 if (h.float_field == 3.14f)
1391                         return 0;
1392                 else
1393                         return 1;
1394         }
1395
1396         class R4HolderRemote : MarshalByRefObject {
1397                 public static float pi = 3.14f;
1398
1399                 public float float_field;
1400         }
1401
1402         public static int test_0_ldfld_stfld_soft_float_remote () {
1403                 R4HolderRemote h = new R4HolderRemote ();
1404                 h.float_field = 3.14f;
1405
1406                 if (h.float_field == 3.14f)
1407                         return 0;
1408                 else
1409                         return 1;
1410         }
1411
1412         public static int test_0_locals_soft_float () {
1413                 float f = 0.0f;
1414                 
1415                 f = 3.14f;
1416
1417                 if (f == 3.14f)
1418                         return 0;
1419                 else
1420                         return 1;
1421         }
1422
1423         struct AStruct2 {
1424                 public int i;
1425                 public int j;
1426         }
1427
1428         static float pass_vtype_return_float (AStruct2 s) {
1429                 return s.i + s.j == 6 ? 1.0f : -1.0f;
1430         }
1431
1432         public static int test_0_vtype_arg_soft_float () {
1433                 return pass_vtype_return_float (new AStruct2 () { i = 2, j = 4 }) > 0.0 ? 0 : 1;
1434         }
1435
1436         static int range_check_strlen (int i, string s) {
1437                 if (i < 0 || i > s.Length)
1438                         return 1;
1439                 else
1440                         return 0;
1441         }
1442                 
1443         public static int test_0_range_check_opt () {
1444                 if (range_check_strlen (0, "A") != 0)
1445                         return 1;
1446                 if (range_check_strlen (1, "A") != 0)
1447                         return 2;
1448                 if (range_check_strlen (2, "A") != 1)
1449                         return 3;
1450                 if (range_check_strlen (-100, "A") != 1)
1451                         return 4;
1452                 return 0;
1453         }
1454
1455         static int test_0_array_get_set_soft_float () {
1456                 float[,] arr = new float [2, 2];
1457                 arr [0, 0] = 256f;
1458                 return arr [0, 0] == 256f ? 0 : 1;
1459         }
1460
1461         //repro for #506915
1462         struct Bug506915 { public int val; }
1463         static int test_2_ldobj_stobj_optization ()
1464         {
1465                 int i = 99;
1466                 var a = new Bug506915 ();
1467                 var b = new Bug506915 ();
1468                 if (i.GetHashCode () == 99)
1469                         i = 44;
1470                 var array = new Bug506915 [2];
1471                 array [0].val = 2;
1472                 array [1] = (i == 0) ? a : array [0];
1473                 
1474                 return array [1].val;
1475         }
1476
1477         /* mcs can't compile this (#646744) */
1478 #if FALSE
1479         static void InitMe (out Gamma noMercyWithTheStack) {
1480                 noMercyWithTheStack = new Gamma ();
1481         }
1482
1483         static int FunNoInline () {
1484                 int x = 99;
1485                 if (x > 344 && x < 22)
1486                         return 333;
1487                 return x;
1488         }
1489
1490         static float DoNothingButDontInline (float a, int b) {
1491                 if (b > 0)
1492                         return a;
1493                 else if (b < 0 && b > 10)
1494                         return 444.0f;
1495                 return a;
1496         }
1497
1498         /*
1499          * The local register allocator emits loadr8_membase and storer8_membase
1500          * to do spilling. This code is generated after mono_arch_lowering_pass so
1501          * mono_arch_output_basic_block must know how to deal with big offsets.
1502          * This only happens because the call in middle forces the temp for "(float)obj"
1503          * to be spilled.
1504         */
1505         public static int test_0_float_load_and_store_with_big_offset ()
1506         {
1507                 object obj = 1.0f;
1508                 Gamma noMercyWithTheStack;
1509                 float res;
1510
1511                 InitMe (out noMercyWithTheStack);
1512
1513                 res = DoNothingButDontInline ((float)obj, FunNoInline ());
1514
1515                 if (!(res == 1.0f))
1516                         return 1;
1517                 return 0;
1518         }
1519 #endif
1520
1521         struct VTypePhi {
1522                 public int i;
1523         }
1524
1525         static int vtype_phi (VTypePhi v1, VTypePhi v2, bool first) {
1526                 VTypePhi v = first ? v1 : v2;
1527
1528                 return v.i;
1529         }
1530
1531         static int test_0_vtype_phi ()
1532         {
1533                 VTypePhi v1 = new VTypePhi () { i = 1 };
1534                 VTypePhi v2 = new VTypePhi () { i = 2 };
1535
1536                 if (vtype_phi (v1, v2, true) != 1)
1537                         return 1;
1538                 if (vtype_phi (v1, v2, false) != 2)
1539                         return 2;
1540
1541                 return 0;
1542         }
1543
1544         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1545         static void UseValue (int index)
1546         {
1547         }
1548
1549         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1550         static bool IsFalse ()
1551         {
1552                 return false;
1553         }
1554
1555         static int test_0_llvm_moving_faulting_loads ()
1556         {
1557                 int[] indexes = null;
1558
1559                 if (IsFalse ()) {
1560                         indexes = new int[0];
1561                 }
1562                         
1563                 while (IsFalse ()) {
1564                         UseValue (indexes[0]);
1565                         UseValue (indexes[0]);
1566                 }
1567
1568                 return 0;
1569         }
1570
1571         public static bool flag;
1572
1573         class B {
1574
1575                 internal static B[] d;
1576
1577                 static B () {
1578                         flag = true;
1579                 }
1580         }
1581
1582         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1583         static int regress_679467_inner () {
1584                 if (flag == true)
1585                         return 1;
1586                 var o = B.d;
1587                 var o2 = B.d;
1588                 return 0;
1589         }
1590
1591         /*
1592          * FIXME: This fails with AOT #703317.
1593          */
1594         /*
1595         static int test_0_multiple_cctor_calls_regress_679467 () {
1596                 flag = false;
1597                 return regress_679467_inner ();
1598         }
1599         */
1600
1601         static int test_0_char_ctor () {
1602                 string s = new String (new char[] { 'A', 'B' }, 0, 1);
1603                 return 0;
1604         }
1605
1606         static object mInstance = null;
1607
1608         [MethodImpl(MethodImplOptions.Synchronized)]
1609         public static object getInstance() {
1610                 if (mInstance == null)
1611                         mInstance = new object();
1612                 return mInstance;
1613         }
1614
1615         static int test_0_synchronized () {
1616                 getInstance ();
1617                 return 0;
1618         }
1619
1620         struct BStruct {
1621                 public Type t;
1622         }
1623
1624         class Del<T> {
1625                 public static BStruct foo () {
1626                         return new BStruct () { t = typeof (T) };
1627                 }
1628         }
1629
1630         delegate BStruct ADelegate ();
1631
1632         static int test_0_regress_10601 () {
1633                 var act = (ADelegate)(Del<string>.foo);
1634                 BStruct b = act ();
1635                 if (b.t != typeof (string))
1636                         return 1;
1637                 return 0;
1638         }
1639
1640         static int test_0_regress_11058 () {
1641                 int foo = -252674008;
1642                 int foo2 = (int)(foo ^ 0xF0F0F0F0); // = 28888
1643                 var arr = new byte[foo2].Length;
1644                 return 0;
1645         }
1646
1647         public static void do_throw () {
1648                 throw new Exception ();
1649         }
1650
1651         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1652         static void empty () {
1653         }
1654
1655         // #11297
1656         public static int test_0_llvm_inline_throw () {
1657                 try {
1658                         empty ();
1659                 } catch (Exception) {
1660                         do_throw ();
1661                 }
1662
1663                 return 0;
1664         }
1665
1666         enum ByteEnum : byte {
1667         Zero = 0
1668     }
1669
1670     struct BugStruct {
1671         public ByteEnum f1;
1672         public ByteEnum f2;
1673         public ByteEnum f3;
1674         public byte f4;
1675         public byte f5;
1676         public byte f6;
1677         public byte f7;
1678     }
1679
1680         public static int test_0_14217 () {
1681                 t_14217_inner (new BugStruct ());
1682                 return 0;
1683         }
1684
1685         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1686         static void t_14217_inner (BugStruct bug) {
1687     }
1688
1689         [StructLayout(LayoutKind.Sequential)]
1690         public struct EmptyStruct {
1691         }
1692
1693         class EmptyClass {
1694                 public static EmptyStruct s;
1695         }
1696
1697         // #20349
1698         static int test_0_empty_struct_as_static () {
1699                 var s = EmptyClass.s;
1700                 return 0;
1701         }
1702
1703         // #25487
1704         static int test_0_int_to_r4 () {
1705                 return int_to_r4_inner (255);
1706         }
1707
1708         static int int_to_r4_inner (int value1) {
1709                 int sub = -value1;
1710                 float mult = sub * 1f;
1711                 if (mult != -255.0f)
1712                         return 1;
1713                 else
1714                         return 0;
1715         }
1716
1717         struct HFA4D {
1718                 public double a, b, c, d;
1719         }
1720
1721         static double arm64_hfa_on_stack_inner (double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, HFA4D s) {
1722                 return s.a + s.b + s.c + s.d;
1723         }
1724
1725         static int test_0_arm64_hfa_on_stack () {
1726                 var s = new HFA4D () { a = 1.0, b = 2.0, c = 3.0, d = 4.0 };
1727                 var res = arm64_hfa_on_stack_inner (1, 2, 3, 4, 5, 6, 7, 8, s);
1728                 return res == 10.0 ? 0 : 1;
1729         }
1730
1731         class MulOvfClass {
1732                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1733                 public unsafe void EncodeIntoBuffer(char* value, int valueLength, char* buffer, int bufferLength) {
1734                 }
1735         }
1736
1737         static unsafe int test_0_mul_ovf_regress_36052 () {
1738                 var p = new MulOvfClass ();
1739
1740                 string typeName = typeof(int).Name;
1741                 int bufferSize = 45;
1742
1743                 fixed (char* value = typeName) {
1744                         char* buffer = stackalloc char[bufferSize];
1745                         p.EncodeIntoBuffer(value, typeName.Length, buffer, bufferSize);
1746                 }
1747                 return 0;
1748         }
1749
1750         struct Struct16 {
1751                 public int a, b, c, d;
1752         }
1753
1754         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1755         static int pass_struct16 (object o0, object o2, object o3, object o4, object o5, object o6, object o7, Struct16 o8) {
1756                 // This disables LLVM
1757                 try {
1758                 } catch {
1759                 }
1760                 return o8.a;
1761         }
1762
1763         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1764         static int pass_struct16 (object o0, object o2, object o3, object o6, object o7, Struct16 o8) {
1765                 return pass_struct16 (o0, o2, null, o3, null, o6, o7, o8);
1766         }
1767
1768         public static int test_42_pass_16byte_struct_split () {
1769                 return pass_struct16 (null, null, null, null, null, new Struct16 () { a = 42 });
1770         }
1771
1772         public interface IComparer2
1773         {
1774                 Type foo<T> ();
1775         }
1776
1777         public class AClass : IComparer2 {
1778                 public Type foo<T> () {
1779                         return typeof(T);
1780                 }
1781         }
1782
1783         public static int test_0_delegate_to_virtual_generic_on_ifaces () {
1784                 IComparer2 c = new AClass ();
1785
1786                 Func<Type> f = c.foo<string>;
1787                 return f () == typeof(string) ? 0 : 1;
1788         }
1789
1790         public enum ByteEnum2 : byte {
1791                 High = 142
1792         }
1793
1794         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1795         public static int enum_arg_zero_extend (ByteEnum2 b) {
1796                 return (int)b;
1797         }
1798
1799         public static int test_142_byte_enum_arg_zero_extend () {
1800                 return enum_arg_zero_extend (ByteEnum2.High);
1801         }
1802
1803         enum Mine { One, Two }
1804
1805         public static int test_0_enum_gethashcode_opt () {
1806                 int sum = 0;
1807         for (int i = 0; i < 1000000; ++i)
1808                         sum += Mine.Two.GetHashCode();
1809
1810         return 0;
1811     }
1812
1813         public static int test_0_typedref () {
1814                 int i = 5;
1815                 System.TypedReference r = __makeref(i);
1816                 System.Type t = __reftype(r);
1817
1818                 if (t != typeof (int))
1819                         return 1;
1820                 int j = __refvalue(r, int);
1821                 if (j != 5)
1822                         return 2;
1823
1824                 try {
1825                         object o = __refvalue (r, object);
1826                 } catch (InvalidCastException) {
1827                 }
1828
1829                 return 0;
1830         }
1831 }
1832
1833 #if __MOBILE__
1834 }
1835 #endif