merged Sys.Web.Services 2.0 support in my branch:
[mono.git] / mono / mini / basic-calls.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  * 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 class Tests {
27
28         static int Main () {
29                 return TestDriver.RunTests (typeof (Tests));
30         }
31
32         static void dummy () {
33         }
34
35         static int test_0_return () {
36                 dummy ();
37                 return 0;
38         }
39
40         static int dummy1 () {
41                 return 1;
42         }
43
44         static int test_2_int_return () {
45                 int r = dummy1 ();
46                 if (r == 1)
47                         return 2;
48                 return 0;
49         }
50
51         static int add1 (int val) {
52                 return val + 1;
53         }
54
55         static int test_1_int_pass () {
56                 int r = add1 (5);
57                 if (r == 6)
58                         return 1;
59                 return 0;
60         }
61
62         static int add_many (int val, short t, byte b, int da) {
63                 return val + t + b + da;
64         }
65
66         static int test_1_int_pass_many () {
67                 byte b = 6;
68                 int r = add_many (5, 2, b, 1);
69                 if (r == 14)
70                         return 1;
71                 return 0;
72         }
73
74         unsafe static float GetFloat (byte *ptr) {
75                 return *(float*)ptr;
76         }
77
78         unsafe public static float GetFloat(float value)
79                 {
80                         return GetFloat((byte *)&value);
81                 }
82
83         /* bug #42134 */
84         static int test_2_inline_saved_arg_type () {
85                 float f = 100.0f;
86                 return GetFloat (f) == f? 2: 1;
87         }
88
89         static int pass_many_types (int a, long b, int c, long d) {
90                 return a + (int)b + c + (int)d;
91         }
92
93         static int test_5_pass_longs () {
94                 return pass_many_types (1, 2, -5, 7);
95         }
96
97         static int overflow_registers (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
98                 return a+b+c+d+e+f+g+h+i+j;
99         }
100
101         static int test_55_pass_even_more () {
102                 return overflow_registers (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
103         }
104
105         static int pass_ints_longs (int a, long b, long c, long d, long e, int f, long g) {
106                 return (int)(a + b + c + d + e + f + g);
107         }
108
109         static int test_1_sparc_argument_passing () {
110                 // The 4. argument tests split reg/mem argument passing
111                 // The 5. argument tests mem argument passing
112                 // The 7. argument tests passing longs in misaligned memory
113                 // The MaxValues are needed so the MS word of the long is not 0
114                 return pass_ints_longs (1, 2, System.Int64.MaxValue, System.Int64.MinValue, System.Int64.MaxValue, 0, System.Int64.MinValue);
115         }
116
117         static int pass_bytes (byte a, byte b, byte c, byte d, byte e, byte f, byte g) {
118                 return (int)(a + b + c + d + e + f + g);
119         }
120
121         static int test_21_sparc_byte_argument_passing () {
122                 return pass_bytes (0, 1, 2, 3, 4, 5, 6);
123         }
124
125         static int pass_sbytes (sbyte a, sbyte b, sbyte c, sbyte d, sbyte e, sbyte f, sbyte g) {
126                 return (int)(a + b + c + d + e + f + g);
127         }
128
129         static int test_21_sparc_sbyte_argument_passing () {
130                 return pass_sbytes (0, 1, 2, 3, 4, 5, 6);
131         }
132
133         static int pass_shorts (short a, short b, short c, short d, short e, short f, short g) {
134                 return (int)(a + b + c + d + e + f + g);
135         }
136
137         static int test_21_sparc_short_argument_passing () {
138                 return pass_shorts (0, 1, 2, 3, 4, 5, 6);
139         }
140
141         static int pass_floats_doubles (float a, double b, double c, double d, double e, float f, double g) {
142                 return (int)(a + b + c + d + e + f + g);
143         }
144
145         static int test_721_sparc_float_argument_passing () {
146                 return pass_floats_doubles (100.0f, 101.0, 102.0, 103.0, 104.0, 105.0f, 106.0);
147         }
148
149         static float pass_floats (float a, float b, float c, float d, float e, float f, float g, float h, float i, float j) {
150                 return a + b + c + d + e + f + g + h + i + j;
151         }
152
153         static int test_55_sparc_float_argument_passing2 () {
154                 return (int)pass_floats (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f);
155         }
156
157         // The first argument must be passed on a dword aligned stack location
158         static int pass_byref_ints_longs (ref long a, ref int b, ref byte c, ref short d, ref long e, ref int f, ref long g) {
159                 return (int)(a + b + c + d + e + f + g);
160         }
161
162         static int pass_takeaddr_ints_longs (long a, int b, byte c, short d, long e, int f, long g) {
163                 return pass_byref_ints_longs (ref a, ref b, ref c, ref d, ref e, ref f, ref g);
164         }
165
166         // Test that arguments are moved to the stack from incoming registers
167         // when the argument must reside in the stack because its address is taken
168         static int test_2_sparc_takeaddr_argument_passing () {
169                 return pass_takeaddr_ints_longs (1, 2, 253, -253, System.Int64.MaxValue, 0, System.Int64.MinValue);
170         }
171
172         static int pass_byref_floats_doubles (ref float a, ref double b, ref double c, ref double d, ref double e, ref float f, ref double g) {
173                 return (int)(a + b + c + d + e + f + g);
174         }
175
176         static int pass_takeaddr_floats_doubles (float a, double b, double c, double d, double e, float f, double g) {
177                 return pass_byref_floats_doubles (ref a, ref b, ref c, ref d, ref e, ref f, ref g);
178         }
179
180         static int test_721_sparc_takeaddr_argument_passing2 () {
181                 return pass_takeaddr_floats_doubles (100.0f, 101.0, 102.0, 103.0, 104.0, 105.0f, 106.0);
182         }
183
184         static void pass_byref_double (out double d) {
185                 d = 5.0;
186         }
187
188         // Test byref double argument passing
189         static int test_0_sparc_byref_double_argument_passing () {
190                 double d;
191                 pass_byref_double (out d);
192                 return (d == 5.0) ? 0 : 1;
193         }
194
195         static void shift_un_arg (ulong value) {
196                 do {
197                         value = value >> 4;
198                 } while (value != 0);
199         }
200
201         // Test that assignment to long arguments work
202         static int test_0_long_arg_assign ()
203         {
204                 ulong c = 0x800000ff00000000;
205                         
206                 shift_un_arg (c >> 4);
207
208                 return 0;
209         }
210
211         static unsafe void* ptr_return (void *ptr)
212         {
213                 return ptr;
214         }
215
216         static unsafe int test_0_ptr_return ()
217         {
218                 void *ptr = new IntPtr (55).ToPointer ();
219
220                 if (ptr_return (ptr) == ptr)
221                         return 0;
222                 else
223                         return 1;
224         }
225
226         static bool isnan (float f) {
227                 return (f != f);
228         }
229
230         static int test_0_isnan () {
231                 float f = 1.0f;
232                 return isnan (f) ? 1 : 0;
233         }
234
235         static int first_is_zero (int v1, int v2) {
236                 if (v1 != 0)
237                         return -1;
238                 return v2;
239         }
240         static int test_1_handle_dup_stloc () {
241                 int index = 0;
242                 int val = first_is_zero (index, ++index);
243                 if (val != 1)
244                         return 2;
245                 return 1;
246         }
247
248         static long return_5low () {
249                 return 5;
250         }
251         
252         static long return_5high () {
253                 return 0x500000000;
254         }
255
256         public static int test_3_long_ret () {
257                 long val = return_5low ();
258                 return (int) (val - 2);
259         }
260
261         public static int test_1_long_ret2 () {
262                 long val = return_5high ();
263                 if (val > 0xffffffff)
264                         return 1;
265                 return 0;
266         }
267
268         // 64-bits, 32-bit aligned
269         struct struct1 {
270                 public int      a;
271                 public int      b;
272         };
273
274         static int check_struct1(struct1 x) {
275                 if (x.a != 1)
276                         return 1;
277                 if (x.b != 2)
278                         return 2;
279                 return 0;
280         }
281
282         static int pass_struct1(int a, int b, struct1 x) {
283                 if (a != 3)
284                         return 3;
285                 if (b != 4)
286                         return 4;
287                 return check_struct1(x);
288         }
289
290         static int pass_struct1(int a, struct1 x) {
291                 if (a != 3)
292                         return 3;
293                 return check_struct1(x);
294         }
295
296         static int pass_struct1(struct1 x) {
297                 return check_struct1(x);
298         }
299
300         static int test_0_struct1_args () {
301                 int r;
302                 struct1 x;
303
304                 x.a = 1;
305                 x.b = 2;
306                 if ((r = check_struct1(x)) != 0)
307                         return r;
308                 if ((r = pass_struct1(x)) != 0)
309                         return r + 10;
310                 if ((r = pass_struct1(3, x)) != 0)
311                         return r + 20;
312                 if ((r = pass_struct1(3, 4, x)) != 0)
313                         return r + 30;
314                 return 0;
315         }
316
317         // 64-bits, 64-bit aligned
318         struct struct2 {
319                 public long     a;
320         };
321
322         static int check_struct2(struct2 x) {
323                 if (x.a != 1)
324                         return 1;
325                 return 0;
326         }
327
328         static int pass_struct2(int a, int b, int c, struct2 x) {
329                 if (a != 3)
330                         return 3;
331                 if (b != 4)
332                         return 4;
333                 if (c != 5)
334                         return 5;
335                 return check_struct2(x);
336         }
337
338         static int pass_struct2(int a, int b, struct2 x) {
339                 if (a != 3)
340                         return 3;
341                 if (b != 4)
342                         return 4;
343                 return check_struct2(x);
344         }
345
346         static int pass_struct2(int a, struct2 x) {
347                 if (a != 3)
348                         return 3;
349                 return check_struct2(x);
350         }
351
352         static int pass_struct2(struct2 x) {
353                 return check_struct2(x);
354         }
355
356         static int test_0_struct2_args () {
357                 int r;
358                 struct2 x;
359
360                 x.a = 1;
361                 if ((r = check_struct2(x)) != 0)
362                         return r;
363                 if ((r = pass_struct2(x)) != 0)
364                         return r + 10;
365                 if ((r = pass_struct2(3, x)) != 0)
366                         return r + 20;
367                 if ((r = pass_struct2(3, 4, x)) != 0)
368                         return r + 30;
369                 if ((r = pass_struct2(3, 4, 5, x)) != 0)
370                         return r + 40;
371                 return 0;
372         }
373
374         static void doit (double value, out long m) {
375                 m = (long) value;
376         }
377
378         public static int test_0_ftol_clobber () {
379                 long m;
380                 doit (1.3, out m);
381                 if (m != 1)
382                         return 2;
383                 return 0;
384         }
385
386 }
387