2 using System
.Reflection
;
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
34 public static int Main (string[] args
) {
35 return TestDriver
.RunTests (typeof (Tests
), args
);
39 static void dummy () {
42 public static int test_0_return () {
47 static int dummy1 () {
51 public static int test_2_int_return () {
58 static int add1 (int val
) {
62 public static int test_1_int_pass () {
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 () {
75 int r
= add_many (5, 2, b
, 1);
81 unsafe static float GetFloat (byte *ptr
) {
85 unsafe public static float GetFloat(float value)
87 return GetFloat((byte *)&value);
91 public static int test_2_inline_saved_arg_type () {
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
) {
206 // Test byref double argument passing
207 public static int test_0_sparc_byref_double_argument_passing () {
209 pass_byref_double (out d
);
210 return (d
== 5.0) ? 0 : 1;
213 static void shift_un_arg (ulong value) {
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);
229 static unsafe void* ptr_return (void *ptr
)
234 public static unsafe int test_0_ptr_return ()
236 void *ptr
= new IntPtr (55).ToPointer ();
238 if (ptr_return (ptr
) == ptr
)
244 static bool isnan (float f
) {
248 public static int test_0_isnan () {
250 return isnan (f
) ? 1 : 0;
253 static int first_is_zero (int v1
, int v2
) {
258 public static int test_1_handle_dup_stloc () {
260 int val
= first_is_zero (index
, ++index
);
266 static long return_5low () {
270 static long return_5high () {
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)
286 public static void use_long_arg (ulong l
) {
287 for (int i
= 0; i
< 10; ++i
)
291 public static ulong return_long_arg (object o
, ulong perm
) {
294 perm
= 0x8000000000000FFF;
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
) {
313 public static int test_0_ftol_clobber () {
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
;
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
;
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);
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;