[interp] Fix interp logging (#17636)
[mono-project.git] / mono / mini / basic-calls.cs
blobad3cdde59a1f3284f151948cf5441b6910db2fd8
1 using System;
2 using System.Reflection;
4 /*
5 * Regression tests for the mono JIT.
7 * Each test needs to be of the form:
9 * public static int test_<result>_<name> ();
11 * where <result> is an integer (the value that needs to be returned by
12 * the method to make it pass.
13 * <name> is a user-displayed name used to identify the test.
15 * The tests can be driven in two ways:
16 * *) running the program directly: Main() uses reflection to find and invoke
17 * the test methods (this is useful mostly to check that the tests are correct)
18 * *) with the --regression switch of the jit (this is the preferred way since
19 * all the tests will be run with optimizations on and off)
21 * The reflection logic could be moved to a .dll since we need at least another
22 * regression test file written in IL code to have better control on how
23 * the IL code looks.
26 #if __MOBILE__
27 class CallsTests
28 #else
29 class Tests
30 #endif
33 #if !__MOBILE__
34 public static int Main (string[] args) {
35 return TestDriver.RunTests (typeof (Tests), args);
37 #endif
39 static void dummy () {
42 public static int test_0_return () {
43 dummy ();
44 return 0;
47 static int dummy1 () {
48 return 1;
51 public static int test_2_int_return () {
52 int r = dummy1 ();
53 if (r == 1)
54 return 2;
55 return 0;
58 static int add1 (int val) {
59 return val + 1;
62 public static int test_1_int_pass () {
63 int r = add1 (5);
64 if (r == 6)
65 return 1;
66 return 0;
69 static int add_many (int val, short t, byte b, int da) {
70 return val + t + b + da;
73 public static int test_1_int_pass_many () {
74 byte b = 6;
75 int r = add_many (5, 2, b, 1);
76 if (r == 14)
77 return 1;
78 return 0;
81 unsafe static float GetFloat (byte *ptr) {
82 return *(float*)ptr;
85 unsafe public static float GetFloat(float value)
87 return GetFloat((byte *)&value);
90 /* bug #42134 */
91 public static int test_2_inline_saved_arg_type () {
92 float f = 100.0f;
93 return GetFloat (f) == f? 2: 1;
96 static int pass_many_types (int a, long b, int c, long d) {
97 return a + (int)b + c + (int)d;
100 public static int test_5_pass_longs () {
101 return pass_many_types (1, 2, -5, 7);
104 static int overflow_registers (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
105 return a+b+c+d+e+f+g+h+i+j;
108 public static int test_55_pass_even_more () {
109 return overflow_registers (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
112 static int pass_ints_longs (int a, long b, long c, long d, long e, int f, long g) {
113 return (int)(a + b + c + d + e + f + g);
116 public static int test_1_sparc_argument_passing () {
117 // The 4. argument tests split reg/mem argument passing
118 // The 5. argument tests mem argument passing
119 // The 7. argument tests passing longs in misaligned memory
120 // The MaxValues are needed so the MS word of the long is not 0
121 return pass_ints_longs (1, 2, System.Int64.MaxValue, System.Int64.MinValue, System.Int64.MaxValue, 0, System.Int64.MinValue);
124 static int pass_bytes (byte a, byte b, byte c, byte d, byte e, byte f, byte g) {
125 return (int)(a + b + c + d + e + f + g);
128 public static int test_21_sparc_byte_argument_passing () {
129 return pass_bytes (0, 1, 2, 3, 4, 5, 6);
132 static int pass_sbytes (sbyte a, sbyte b, sbyte c, sbyte d, sbyte e, sbyte f, sbyte g, sbyte h1, sbyte h2, sbyte h3, sbyte h4) {
133 return (int)(a + b + c + d + e + f + g + h1 + h2 + h3 + h4);
136 public static int test_55_sparc_sbyte_argument_passing () {
137 return pass_sbytes (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
140 static int pass_shorts (short a, short b, short c, short d, short e, short f, short g) {
141 return (int)(a + b + c + d + e + f + g);
144 public static int test_21_sparc_short_argument_passing () {
145 return pass_shorts (0, 1, 2, 3, 4, 5, 6);
148 static int pass_floats_doubles (float a, double b, double c, double d, double e, float f, double g) {
149 return (int)(a + b + c + d + e + f + g);
152 public static int test_721_sparc_float_argument_passing () {
153 return pass_floats_doubles (100.0f, 101.0, 102.0, 103.0, 104.0, 105.0f, 106.0);
156 static float pass_floats (float a, float b, float c, float d, float e, float f, float g, float h, float i, float j) {
157 return a + b + c + d + e + f + g + h + i + j;
160 public static int test_55_sparc_float_argument_passing2 () {
161 return (int)pass_floats (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f);
164 public static bool is_small (float value) {
165 double d = (double)value;
166 double d2 = 7.183757E-41;
167 return d - d2 < 0.000001;
170 public static int test_0_float_argument_passing_precision () {
171 float f = 7.183757E-41f;
172 return is_small (f) ? 0 : 1;
175 // The first argument must be passed on a dword aligned stack location
176 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) {
177 return (int)(a + b + c + d + e + f + g);
180 static int pass_takeaddr_ints_longs (long a, int b, byte c, short d, long e, int f, long g) {
181 return pass_byref_ints_longs (ref a, ref b, ref c, ref d, ref e, ref f, ref g);
184 // Test that arguments are moved to the stack from incoming registers
185 // when the argument must reside in the stack because its address is taken
186 public static int test_2_sparc_takeaddr_argument_passing () {
187 return pass_takeaddr_ints_longs (1, 2, 253, -253, System.Int64.MaxValue, 0, System.Int64.MinValue);
190 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) {
191 return (int)(a + b + c + d + e + f + g);
194 static int pass_takeaddr_floats_doubles (float a, double b, double c, double d, double e, float f, double g) {
195 return pass_byref_floats_doubles (ref a, ref b, ref c, ref d, ref e, ref f, ref g);
198 public static int test_721_sparc_takeaddr_argument_passing2 () {
199 return pass_takeaddr_floats_doubles (100.0f, 101.0, 102.0, 103.0, 104.0, 105.0f, 106.0);
202 static void pass_byref_double (out double d) {
203 d = 5.0;
206 // Test byref double argument passing
207 public static int test_0_sparc_byref_double_argument_passing () {
208 double d;
209 pass_byref_double (out d);
210 return (d == 5.0) ? 0 : 1;
213 static void shift_un_arg (ulong value) {
214 do {
215 value = value >> 4;
216 } while (value != 0);
219 // Test that assignment to long arguments work
220 public static int test_0_long_arg_assign ()
222 ulong c = 0x800000ff00000000;
224 shift_un_arg (c >> 4);
226 return 0;
229 static unsafe void* ptr_return (void *ptr)
231 return ptr;
234 public static unsafe int test_0_ptr_return ()
236 void *ptr = new IntPtr (55).ToPointer ();
238 if (ptr_return (ptr) == ptr)
239 return 0;
240 else
241 return 1;
244 static bool isnan (float f) {
245 return (f != f);
248 public static int test_0_isnan () {
249 float f = 1.0f;
250 return isnan (f) ? 1 : 0;
253 static int first_is_zero (int v1, int v2) {
254 if (v1 != 0)
255 return -1;
256 return v2;
258 public static int test_1_handle_dup_stloc () {
259 int index = 0;
260 int val = first_is_zero (index, ++index);
261 if (val != 1)
262 return 2;
263 return 1;
266 static long return_5low () {
267 return 5;
270 static long return_5high () {
271 return 0x500000000;
274 public static int test_3_long_ret () {
275 long val = return_5low ();
276 return (int) (val - 2);
279 public static int test_1_long_ret2 () {
280 long val = return_5high ();
281 if (val > 0xffffffff)
282 return 1;
283 return 0;
286 public static void use_long_arg (ulong l) {
287 for (int i = 0; i < 10; ++i)
288 l ++;
291 public static ulong return_long_arg (object o, ulong perm) {
292 use_long_arg (perm);
294 perm = 0x8000000000000FFF;
296 use_long_arg (perm);
298 return perm;
301 public static int test_0_sparc_long_ret_regress_541577 () {
302 ulong perm = 0x8000000000000FFF;
304 ulong work = return_long_arg (null, perm);
306 return work == perm ? 0 : 1;
309 static void doit (double value, out long m) {
310 m = (long) value;
313 public static int test_0_ftol_clobber () {
314 long m;
315 doit (1.3, out m);
316 if (m != 1)
317 return 2;
318 return 0;
321 public static bool arm64_stack_arg_reg_bool (object o1, object o2, object o3, object o4, object o5, object o6, object o7,
322 bool foo, bool bar) {
323 bool res1 = bar || foo;
324 bool res2 = bar || foo;
325 return res1 | res2;
328 public static int arm64_stack_arg_reg_sbyte (object o1, object o2, object o3, object o4, object o5, object o6, object o7,
329 sbyte foo, sbyte bar) {
330 int res1 = bar + foo;
331 int res2 = bar + foo;
332 return res1 + res2;
335 // bool argument passed on the stack and promoted to a register
336 public static int test_0_arm64_stack_arg_reg_bool () {
337 bool res = arm64_stack_arg_reg_bool (null, null, null, null, null, null, null, false, false);
338 return res ? 1 : 0;
341 public static int test_0_arm64_stack_arg_reg_sbyte () {
342 int res = arm64_stack_arg_reg_sbyte (null, null, null, null, null, null, null, -4, -7);
343 return res == -22 ? 0 : 1;